Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TextInput crashes an app if Samsung Keyboard uses Predictive Text & Suggest text corrections #33139

Closed
BohdanSol opened this issue Feb 18, 2022 · 63 comments
Labels

Comments

@BohdanSol
Copy link

Description

Main issue: Generated release .apk TextInput crash the app on Samsung when Predictive Text & Suggest text corrections is activated.
React-native versions checked: 0.63.3, 0.67.2
Phones produced the issue: Samsung S20 Ultra, Samsung Galaxy S21 Plus
Another possible issue: For all the crashes captured some parts of the text were underlined green or red, maybe the issue is with that suggestions...
It was first produced by the production project based on 0.63.3v, then I created bare 0.67.2v project and added simple TextInput, and the issue still exists. Attaching a video so everybody can replicate.

Screenshot_20220216-094239_Samsung_Keyboard

record-20220217-094302.mp4

Version

0.63.3, 0.67.2

Output of npx react-native info

System:
OS: macOS 12.2.1
CPU: (8) arm64 Apple M1
Memory: 439.56 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 17.2.0 - /opt/homebrew/bin/node
Yarn: 1.22.17 - /opt/homebrew/bin/yarn
npm: 8.1.2 - /usr/local/bin/npm
Watchman: 2021.12.13.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.2 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.2, iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3
Android SDK:
API Levels: 29, 30, 32
Build Tools: 28.0.3, 29.0.2, 30.0.0, 30.0.2, 32.0.0
System Images: android-29 | Google APIs Intel x86 Atom, android-29 | Google Play ARM 64 v8a, android-31 | Google APIs ARM 64 v8a, android-32 | Google APIs ARM 64 v8a, android-32 | Google APIs Intel x86 Atom_64
Android NDK: Not Found
IDEs:
Android Studio: 2020.3 AI-203.7717.56.2031.7935034
Xcode: 13.2.1/13C100 - /usr/bin/xcodebuild
Languages:
Java: 1.8.0_292 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 17.0.2 => 17.0.2
react-native: 0.67.2 => 0.67.2
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found

Steps to reproduce

  1. Get my repo: https://github.com/BohdanSol/projectTwo
  2. yarn install
  3. Generate keystore, put it inside android>app. Change values regarding keystore inside gradlew.properties
  4. From root cd android && ./gradlew assembleRelease
  5. Test generated apk in real device

Snack, code example, screenshot, or link to a repository

https://github.com/BohdanSol/projectTwo

@BohdanSol
Copy link
Author

UPD: Seems like it's related with Samsung devices upgraded to Android 12

@kcsuyog
Copy link

kcsuyog commented Feb 21, 2022

I have the same issue.
For us, it's mostly happening with SM-G998B and SM-G991B on Android 12

@tarouboy
Copy link

Not sure is it related but received app crash when typing.
here's the log from Sentry

java.lang.IllegalStateException: Drag shadow dimensions must be positive
    at android.view.View.startDragAndDrop(View.java:26740)
    at android.widget.Editor.startDragAndDrop(Editor.java:1393)
    at android.widget.Editor.performLongClick(Editor.java:1432)
    at android.widget.TextView.performLongClick(TextView.java:12405)

@BohdanSol
Copy link
Author

@tarouboy For me it's:

android.text.SpannableStringInternal in getSpanFlags at line 331
android.text.SpannableString in getSpanFlags at line 24
android.text.SpannableStringInternal in getSpans at line 389
android.text.SpannableString in getSpans at line 24
android.text.SpannableStringBuilder in change at line 431
android.text.SpannableStringBuilder in replace at line 560
android.text.SpannableStringBuilder in replace at line 518
android.text.SpannableStringBuilder in replace at line 39
android.view.inputmethod.BaseInputConnection in replaceText at line 945
android.view.inputmethod.BaseInputConnection in commitText at line 219
com.android.internal.widget.EditableInputConnection in commitText at line 204
com.android.internal.view.IInputConnectionWrapper in executeMessage at line 561
com.android.internal.view.IInputConnectionWrapper$MyHandler in handleMessage at line 118
android.os.Handler in dispatchMessage at line 106
android.os.Looper in loopOnce at line 226
android.os.Looper in loop at line 313
android.app.ActivityThread in main at line 8582
java.lang.reflect.Method in invoke
com.android.internal.os.RuntimeInit$MethodAndArgsCaller in run at line 563
com.android.internal.os.ZygoteInit in main at line 1133

@BohdanSol
Copy link
Author

BohdanSol commented Feb 21, 2022

@JoshuaGross , @RSNara , @mdvacca , sorry for mentioning you all straight, but It seems very important issue for me. Maybe somebody can take at least a quick look at the repo I attached and give this higher priority status.

@rakefetWorkiz
Copy link

we having the exact same issue.
this is real show stopper 🤦‍♀️

@efstathiosntonas
Copy link

efstathiosntonas commented Mar 10, 2022

Any updates regarding this issue? It’s happening on both Android 11 & 12 (rn 0.67.3), we get lot’s of crashes every day. It also lags a lot if a user enters a big block of text and it leads to ANR.

@JuanAlejandro
Copy link

We were able to reproduce this bug and we found that setting autoCorrect to false in the TextInput solves the issue. We are planning to roll out this soon and expect ANR numbers to go down. I'll keep you posted.

Try this and let me know if it works for you.

P.S.: Since this is happening only for Samsung devices with Android 12 I made this util to only set autoCorrect to false when the device meets these props:

import { toLower } from 'lodash';
import { getSystemVersion, useManufacturer } from 'react-native-device-info';

export const useIsSamsungWithAndroid12 = (): boolean => {
  const { loading, result } = useManufacturer();
  const systemVersion = getSystemVersion();

  return !loading && toLower(result) === 'samsung' && systemVersion.startsWith('12');
};

@BohdanSol
Copy link
Author

@JuanAlejandro working as expected as workaround for this kind of issue. Thank you very much!

@systemride
Copy link

@JuanAlejandro Any update on whether your fix continues to solve the issue?

@smali-kazmi
Copy link

any fix for this issue? because lot of our users facing the same issue if they have Samsung Device

@smali-kazmi
Copy link

We were able to reproduce this bug and we found that setting autoCorrect to false in the TextInput solves the issue. We are planning to roll out this soon and expect ANR numbers to go down. I'll keep you posted.

Try this and let me know if it works for you.

P.S.: Since this is happening only for Samsung devices with Android 12 I made this util to only set autoCorrect to false when the device meets these props:

import { toLower } from 'lodash';
import { getSystemVersion, useManufacturer } from 'react-native-device-info';

export const useIsSamsungWithAndroid12 = (): boolean => {
  const { loading, result } = useManufacturer();
  const systemVersion = getSystemVersion();

  return !loading && toLower(result) === 'samsung' && systemVersion.startsWith('12');
};

doesn't fix the issue

@github-actions
Copy link

github-actions bot commented Oct 5, 2022

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Oct 5, 2022
@efstathiosntonas
Copy link

Bad bot, issue still exists to this day

@github-actions github-actions bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Oct 17, 2022
@efstathiosntonas
Copy link

Hey fellow devs, please upvote the comment under the Meta discussion about what to improve: react-native-community/discussions-and-proposals#528 (comment)

let’s hope it will get enough attention

@carstenhag
Copy link

Issue also exists with native android :D so I really don't think React can do anything apart from disabling hints on Samsung

@efstathiosntonas
Copy link

@carstenhag I have many samsung devices, I do not face such an issue with native apps. Can you please link a repro or a link to an issue? Thanks

@carstenhag
Copy link

@efstathiosntonas This is the code that we are using (native android project):

            <EditText
                android:id="@+id/inputFormFieldEditText"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:ellipsize="end"
                android:importantForAutofill="no"
                android:inputType="textFilter|textNoSuggestions"
                android:maxLines="1"
                android:textColor="@{whiteLabelThemePalette.textPrimaryColor}"
                android:textColorHint="@{whiteLabelThemePalette.textInactiveColor}"
                tools:text="Input text" />
        editText.addTextChangedListener(
            TextChangeListener {
                // Clear error text on input change.
                hideErrorText()
            }
        )
// and a few other methods like this, nothing affecting predictions 

Here's a repro description (sorry, only got it as png)
bug-description-1

I can also reproduce it with a Samsung Galaxy S22.

@smali-kazmi
Copy link

This issue is still exist any work around of this issue?

@j-duggirala
Copy link

@smali-kazmi Did you get any work around?

@smali-kazmi
Copy link

@smali-kazmi Did you get any work around?
this fix work for some user but for Android 13 facing the same issue
#33139 (comment)

@JuanAlejandro
Copy link

@smali-kazmi Did you get any work around?
this fix work for some user but for Android 13 facing the same issue
#33139 (comment)

@j-duggirala @smali-kazmi I opened another issue because we are having problems again with Android 13. This time the text suggestions setting is causing the ANRs in our app. The temporary solution we implemented was to set the keyboardType to visible-password. This is not ideal because it adds a lot of limitations to the writing experience of the user but at least doesn't get the app to freeze.

I'm worried about this because this issue was opened almost one year ago and we haven't got one single response from the react-native team.

@Phong-TH
Copy link

@JuanAlejandro I have the same issue on our Samsung devices and received a lot of reports related to it. Just typing a sentence, the application will throw the ANR pop-up and must be forced close, the render thread is running forever. It can be solved by turning off the predictive and spell check but it causes a lot of bad situations 😕 We are crazy about this, any update for this?

@gkasireddy202
Copy link

@JuanAlejandro Any update on this?

@efstathiosntonas
Copy link

Just tested it with Facebook app on a Samsung S22 Android 13 and it ANR, no crash. The amount of entered text was huge when it started lagging compared to my app which starts lagging with much fewer text.

@Houguiram
Copy link

Btw from the manual testing we've done it looks like what makes a difference is wether the TextInput component rerenders on each value change or not. Hence why it crashes a lot for a controlled input or for an uncontrolled input with a defaultValue set to the value updated by onChange, but not for an uncontrolled input with no defaultValue or with a memoized defaultValue.

@nes123
Copy link

nes123 commented Nov 30, 2022

@Houguiram did you check if it makes a difference to use a text child instead of a value to render the input? not sure if it can eliminate the re-renders.

@Houguiram
Copy link

I haven't yet. Could be worth trying if you need a controlled input.

@sabidhasan
Copy link

to use a text child instead of a value to render the input

@nes123 and @Houguiram Can you please elaborate what you mean by this? Sorry I am relatively new to React Native so still not familiar with the terminology/APIs for all of the components.

@nes123
Copy link

nes123 commented Nov 30, 2022

@sabidhasan You can use two forms

<Textinput value={this.state.text}/>

or

<Textinput>
<Text>{this.state.text}</Text>
</Textinput>

I doubt that there is a difference, but worth checking. I am not familiar with Textinput implementation.

@sabidhasan
Copy link

@sabidhasan You can use two forms

<Textinput value={this.state.text}/>

or

<Textinput>
<Text>{this.state.text}</Text>
</Textinput>

I doubt that there is a difference, but worth checking. I am not familiar with Textinput implementation.

Thanks for the response. Confirming that the latter form doesn't make a difference - the keyboard/inputs still slow down after typing ~1 paragraph of text. Appreciate the help/suggeston though!

@Houguiram
Copy link

Now that the change has been rolled out to more users, I can confirm that the issue still happens but way less as can be seen here (11.18.2 contains the change):
image

Here is the exact change we made:

const NoteInput = (props: Props) => {
  const { onChangeText, formikFieldName } = props;
  const { values, setFieldValue } = useFormikContext<FormikNoteInputType>();
  const onChangeTextCallback = React.useCallback(
    (text: string) => {
      setFieldValue(formikFieldName ?? 'note', text);
      onChangeText?.(text);
    },
    [onChangeText, setFieldValue, formikFieldName],
  );

-  const inputValue = formikFieldName ? values[formikFieldName] : values.note;
+  const originalInputValue = useMemo(
+    () => (formikFieldName ? values[formikFieldName] : values.note),
+    // We don't want to rerender the TextInput when the value changes
+    // as it's an uncontrolled input and can create performance issues
+    // with some text suggestion integrations e.g. Grammarly.
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+    [formikFieldName],
+  );

   return (
     <TextInput
       {...props}
-      value={inputValue || ''}
+      defaultValue={originalInputValue || ''}
       onChangeText={onChangeTextCallback}
     />
   );

@KazakovVS
Copy link

Any updates on the issue?

fabOnReact added a commit to fabOnReact/react-native that referenced this issue Dec 20, 2022
…mplete functionality (comment, comment-2, user-comment, user-comment-2) android:inputType=“textFilter|textNoSuggestions”

P | type | task
-- | -- | --
1 | review | Review information from your previous investigation (comment)
1.2 | review | Review comments from Issues facebook#33139 (facebook#30263facebook#35155facebook#35590facebook#35350)
2 | bug | Build RNTester on Android 13 and test TextInput example with Grammarly (example-without-scrollview, example-with-scrollview)
2.1 | task | Enter timemachine and restore previous android sdk configs in folder /Users/fabriziobertoglio/Library/Android/sdk
2.2 | task | Check sdk supported in build.gradle configs in react-native (commit)
2.3 | task | Read react-native environment setup instructions
2.4 | task | Follow instructions on discord to fix build error (1-2 hours)
3 | bug | Add inputType textNoSuggestions in react-native to disable the autocomplete functionality (comment, comment-2, user-comment, user-comment-2) android:inputType=“textFilter\|textNoSuggestions”
3.1 | task | Review implementation of InternalKeyListener
3.2 | task | Find configs inputMode in sourcecode (setKeyboardType)
3.3 | task | Add type “textFilter\|textNoSuggestions” to setKeyboardType
3.4 | task | Test that auto-corrections are disabled in a TextInput with Grammarly Keyboard
3.5 | task | Refactor functionality in branch
3.6 | task | Record test case

P	type	task
1	review	Review information from your previous investigation ([comment](facebook#35590 (comment)))
1.2	review	Review comments from Issues [facebook#33139](facebook#33139) ([facebook#30263](facebook#30263), [facebook#35155](facebook#35155), [facebook#35590](facebook#35590), [facebook#35350](facebook#35350))
2	bug	Build RNTester on Android 13 and test TextInput example with Grammarly ([example-without-scrollview](facebook#35155), [example-with-scrollview](facebook#35590))
2.1	task	Enter timemachine and restore previous android sdk configs in folder /Users/fabriziobertoglio/Library/Android/sdk
2.2	task	Check sdk supported in build.gradle configs in react-native ([commit](394486e))
2.3	task	Read react-native [environment setup instructions](https://reactnative.dev/docs/next/environment-setup)
2.4	task	Follow [instructions on discord](https://discord.com/channels/514829729862516747/1050309907787808768/1050462841028743309) to fix build error (1-2 hours)
3	bug	Add inputType textNoSuggestions in react-native to disable the autocomplete functionality ([comment](facebook#35155 (comment)), [comment-2](facebook#35590 (comment)), [user-comment](facebook#33139 (comment)), [user-comment-2](facebook#33139 (comment))) android:inputType=“textFilter|textNoSuggestions”
3.1	task	Review implementation of [InternalKeyListener](https://github.com/facebook/react-native/blob/76a14454d7f1f2b2ba8f5a79c2f640fafb42de6d/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java#L1153-L1168)
3.2	task	Find configs [inputMode](https://reactnative.dev/docs/next/textinput#inputmode) in sourcecode ([setKeyboardType](https://github.com/facebook/react-native/blob/9f78517d6401f3a7ece453825a059a13b73f6140/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java#L849-L881))
3.3	task	Add type “textFilter|textNoSuggestions” to [setKeyboardType](https://github.com/facebook/react-native/blob/9f78517d6401f3a7ece453825a059a13b73f6140/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java#L849-L881)
3.4	task	Test that auto-corrections are disabled in a TextInput with Grammarly Keyboard
3.5	task	Refactor functionality in branch
3.6	task	Record test case
@fabOnReact
Copy link
Contributor

fabOnReact commented Dec 22, 2022

#35590 (comment)

@Saad-Bashar
Copy link

Now that the change has been rolled out to more users, I can confirm that the issue still happens but way less as can be seen here (11.18.2 contains the change): image

Here is the exact change we made:

const NoteInput = (props: Props) => {
  const { onChangeText, formikFieldName } = props;
  const { values, setFieldValue } = useFormikContext<FormikNoteInputType>();
  const onChangeTextCallback = React.useCallback(
    (text: string) => {
      setFieldValue(formikFieldName ?? 'note', text);
      onChangeText?.(text);
    },
    [onChangeText, setFieldValue, formikFieldName],
  );

-  const inputValue = formikFieldName ? values[formikFieldName] : values.note;
+  const originalInputValue = useMemo(
+    () => (formikFieldName ? values[formikFieldName] : values.note),
+    // We don't want to rerender the TextInput when the value changes
+    // as it's an uncontrolled input and can create performance issues
+    // with some text suggestion integrations e.g. Grammarly.
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+    [formikFieldName],
+  );

   return (
     <TextInput
       {...props}
-      value={inputValue || ''}
+      defaultValue={originalInputValue || ''}
       onChangeText={onChangeTextCallback}
     />
   );

Thanks @Houguiram, I tested your solution and so far it seems to have a far better result. I still have not pushed it to prod. I was just testing on my Samsung device (Android 13).

This video shows ANR and it is the old implementation of our TextInput (Not memoized). This one results in ANR.
https://user-images.githubusercontent.com/13269141/209777762-ab11338f-f216-4160-b943-59d133c29c3f.mp4

This is with memoized.
https://user-images.githubusercontent.com/13269141/209777875-44f26da7-b7de-4867-a2c4-edce0105599b.mp4

@mglobel
Copy link

mglobel commented Dec 29, 2022

For anyone dealing with this issue, the freezing only seems to be happening using the default Samsung keyboard. We've been able to recommend to our users to install Google's Keyboard and the freezing does not happen.

https://play.google.com/store/apps/details?id=com.google.android.inputmethod.latin&hl=en_US&gl=US

Not a great long term solution, but hopefully can help provide some relief while this is investigated.

@smali-kazmi
Copy link

smali-kazmi commented Dec 30, 2022

Hello everyone here are my findings to avoid keyboard crash issue

  1. I changed value={inputValue || ''} to defaultValue={originalInputValue || ''} as suggested by @Houguiram
  2. switch to Microsoft SwiftKey Keyboard or for default Samsung s22 keyboard I turn off following two settings
  3. Suggest Text Corrections or in Manage app disable it for your application
  4. More Typing options > Enhanced accuracy

Screenshot_20221230_152810_Samsung Keyboard
Screenshot_20221230_152823_Samsung Keyboard

@rodrigobertolottizinsp
Copy link

Please we need a solution for this.

@Steve-Rynjah
Copy link

@here any solution on this yet please reply. Thank you.

@gkasireddy202
Copy link

Any solution.

@mglobel
Copy link

mglobel commented Jan 5, 2023

We've finally solved this issue for our app, the root cause was re-renders locking up the UI.

Echoing @Houguiram on this comment #33139 (comment), making the component fully uncontrolled makes a huge difference.

For us we had a class component using Formik, so memoizing wasn't possible. Formik was causing double re-renders every time the user typed. We refactored our component to remove Formik and make sure that zero re-renders happened while typing. This might be complex for some if you're doing something like updating state on the component onDataChanged. We're using mobx as our data store and are simply updating the value in data store with onDataChanged, to be accessed when the form is submitted. Since there's no state update..no re-render.

Obviously it'd still be great to figure out the actual root cause of why this is only happening on Samsung devices. But for those looking for immediate relief, look into how often your components are re-rendering on text changes and try to eliminate/reduce that.

@Saad-Bashar
Copy link

@mglobel did you push the fix to prod? I also had seen a good result which I mentioned here, #33139 (comment)

But I have not yet pushed it to production.

@mglobel
Copy link

mglobel commented Jan 6, 2023

@Saad-Bashar Our fix is currently rolling out. We were also able to see an improvement on our own Samsung Android 13 device. By Monday I should have more confirmation from our users whether the fix is a widespread improvement.

@mglobel
Copy link

mglobel commented Jan 9, 2023

@Saad-Bashar We've rolled out the fix and have confirmation from several users that it resolved the issue for them.

@Saad-Bashar
Copy link

@Saad-Bashar We've rolled out the fix and have confirmation from several users that it resolved the issue for them.

Thanks for the feedback! I just wanted to confirm again, uncontrolled input and removing re-renders solve the issue for you?

@tomwotton
Copy link

I have the same issue and tried some of the solutions but not working fine. Now simply I have fixed this by changing the keyboard type to email-address.

@YuriiLunovSendient
Copy link

YuriiLunovSendient commented Jan 10, 2023

I have the same issue and tried some of the solutions but not working fine. Now simply I have fixed this by changing the keyboard type to email-address.

Thanks this helps, but still not a perfect solution, because of adding "@" and ".com" buttons to the keyboard layout, but works better with multiline inputs than "visible-password" type

@tomwotton
Copy link

@LunyovYuriy yes right its not a perfect solution but its not crashing the app and autocorrect is not working when we use email-address keyboard.

@lunaleaps
Copy link
Contributor

Closing issue as we're addressing in #35590 (comment)

@facebook facebook locked and limited conversation to collaborators Jan 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.