facebookarchive / account-kit-samples-for-android

Account kit sample for the android platform
Other
123 stars 96 forks source link

NullPointerException on Version 5.0.0 #39

Open tysheng opened 5 years ago

tysheng commented 5 years ago

It occurred in production environment, varied from android 4 to 7. Here is the stack trace.

Fatal Exception: java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.facebook.accountkit.ui.PhoneCountryCodeAdapter$ValueData.a' on a null object reference
       at com.facebook.accountkit.ui.PhoneContentController$TopFragment.isPhoneNumberValid(PhoneContentController.java:693)
       at com.facebook.accountkit.ui.PhoneContentController.updateNextButton(PhoneContentController.java:988)
       at com.facebook.accountkit.ui.PhoneContentController.access$900(PhoneContentController.java:63)
       at com.facebook.accountkit.ui.PhoneContentController$2.onPhoneNumberChanged(PhoneContentController.java:897)
       at com.facebook.accountkit.ui.PhoneContentController$TopFragment$2.afterTextChanged(PhoneContentController.java:404)
       at android.widget.TextView.sendAfterTextChanged(TextView.java:8628)
       at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:10838)
       at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1236)
       at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:592)
       at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:524)
       at com.facebook.accountkit.ui.PhoneNumberTextWatcher.afterTextChanged(PhoneNumberTextWatcher.java:73)
       at com.facebook.accountkit.ui.PhoneContentController$TopFragment$2.afterTextChanged(PhoneContentController.java:393)
       at android.widget.TextView.sendAfterTextChanged(TextView.java:8628)
       at android.widget.TextView.setText(TextView.java:4568)
       at android.widget.TextView.setText(TextView.java:4412)
       at android.widget.EditText.setText(EditText.java:95)
       at android.widget.TextView.setText(TextView.java:4387)
       at com.facebook.accountkit.ui.PhoneContentController$TopFragment.setPhoneNumberText(PhoneContentController.java:526)
       at com.facebook.accountkit.ui.PhoneContentController$TopFragment.onViewReadyWithState(PhoneContentController.java:437)
       at com.facebook.accountkit.ui.ViewStateFragment.onActivityCreated(ViewStateFragment.java:66)
       at com.facebook.accountkit.ui.PhoneContentController$TopFragment.onActivityCreated(PhoneContentController.java:275)
       at android.app.Fragment.performActivityCreated(Fragment.java:2362)
       at android.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1022)
       at android.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1179)
       at android.app.BackStackRecord.popFromBackStack(BackStackRecord.java:1750)
       at android.app.FragmentManagerImpl.popBackStackState(FragmentManagerImpl.java:1653)
       at android.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:578)
       at android.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1594)
       at android.app.FragmentManagerImpl$1.run(FragmentManagerImpl.java:491)
       at android.os.Handler.handleCallback(Handler.java:836)
       at android.os.Handler.dispatchMessage(Handler.java:103)
       at android.os.Looper.loop(Looper.java:232)
       at android.app.ActivityThread.main(ActivityThread.java:6661)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1106)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)

Seems the problem is from PhoneContentController

 public boolean isPhoneNumberValid() {
            if (this.phoneNumberView != null && this.countryCodeView != null) {
                String countryCode = "+" + ((ValueData)this.countryCodeView.getSelectedItem()).countryCode; // RIGHT HERE
                String raw = this.phoneNumberView.getText().toString();
                return raw.startsWith(countryCode) && raw.length() != countryCode.length() && this.getPhoneNumber() != null;
            } else {
                return false;
            }
        }
CFFChi commented 5 years ago

Hi tysheng. Thanks for your report.

Would you mind provide a procedure or video to reproduce this bug? Like "click A -> input B".

tysheng commented 5 years ago

@CFFChi Sorry, I cannot reproduce this case myself. But there is another crash case I found. 1.Set white sms list only for ID( Indonesia ), meanwhile my WhatsApp and fb account phone number is a Singapore number, then IndexOutOfBoundError occurred.

val intent = Intent(this, AccountKitActivity::class.java)
val configurationBuilder = AccountKitConfiguration.AccountKitConfigurationBuilder(
                LoginType.PHONE,
                AccountKitActivity.ResponseType.CODE) 
configurationBuilder.setSMSWhitelist(arrayOf("ID"))
intent.putExtra(
                AccountKitActivity.ACCOUNT_KIT_ACTIVITY_CONFIGURATION,
                configurationBuilder.build())
startActivityForResult(intent, APP_REQUEST_CODE)

I guess its cause is that you guys added WhatsApp verification in 5.0.0, will fetch the WhatsApp number when entering AccountKitActivity if there is no default phone number.

Back to the NPE situation, I add one more code to Init phone number

configurationBuilder.setInitialPhoneNumber(PhoneNumber("62", it, "ID"))

Does the PhoneNumber lead to NPE? Or SmsWhiteList? I cannot reproduce, hope you guys can test in different combinations. Thanks.

CFFChi commented 5 years ago

Thanks. I can reproduce it now!=D

tysheng commented 5 years ago

@CFFChi any release updates?

cym4u commented 5 years ago

if user back from [input code] to [enter phone number] page , this would happen. After debug for a while, I found the bug came from here:

image

for a Vietnam phone number(countryCode:84), should this line countryCode = this.phoneCountryCodes[0].**countryCode**; be countryCode = this.phoneCountryCodes[0].**isoCode**;

    public int getIndexOfCountryCode(String countryCode) {
        if (Utility.isNullOrEmpty(countryCode)) {
            return -1;
        } else {
            int length = this.phoneCountryCodes.length;

            for(int i = 0; i < length; ++i) {
                if (countryCode.equalsIgnoreCase(this.phoneCountryCodes[i].isoCode)) {
                    return i;
                }
            }

            return -1;
        }
    }

could you guys fix this?🤣

cym4u commented 5 years ago

update: fixed in sdk v5.2.0