Search code examples
javaandroidfirebasenullpointerexceptionfirebase-authentication

Login to Firebase using phone returns null pointer


I'm trying to follow the tutorial from Firebase to allow users to login using their phone number. I've watched a tutorial video. All my code looks correct, but when I try it on my test device I receive a null pointer error.

 at com.google.android.gms.common.internal.Preconditions.checkNotNull(Unknown Source)
    at com.google.firebase.auth.PhoneAuthProvider.verifyPhoneNumber(Unknown Source)
    at studios.p9p.chatomatic.chat_o_matic.PhoneLogin.CheckPhoneNumber(PhoneLogin.java:92)
    at studios.p9p.chatomatic.chat_o_matic.PhoneLogin.access$000(PhoneLogin.java:29)
    at studios.p9p.chatomatic.chat_o_matic.PhoneLogin$1.onClick(PhoneLogin.java:52)

My code for the phone login is as follows:

private EditText et_check_phone_number;
private EditText et_verify_code;
private Button btn_phone;
private Button btn_verify;
private String getPhoneNumber, getVerifactionCode;
private String mVerificationId = "";
private FirebaseAuth mAuth;
private FirebaseDatabase db;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mcallBacks;
private PhoneAuthProvider.ForceResendingToken mResendToken;
private ProgressDialog mloading;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_phone_login); 

  mAuth = FirebaseAuth.getInstance();
    initVariables();
    btn_phone.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            CheckPhoneNumber();
        }
    });

    btn_verify.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            VerifyPhoneNumber();
        }
    });
}


private void initVariables() {
    et_check_phone_number = findViewById(R.id.et_phonenumber);
    et_verify_code = findViewById(R.id.etvarifaction);
    btn_phone = findViewById(R.id.btn_phone_login);
    btn_verify = findViewById(R.id.btn_phone_verify);
    mloading = new ProgressDialog(this);
}

private void CheckPhoneNumber() {
    getPhoneNumber = et_check_phone_number.getText().toString();

    if (TextUtils.isEmpty(getPhoneNumber))
    {
        Toast.makeText(this, "Phone Number Field Cant Be Empty...", Toast.LENGTH_SHORT).show();
    } else{

                mloading.setTitle("Checking Your Phone Number");
                mloading.setMessage("It Gonna Take A Second...");
                mloading.setCanceledOnTouchOutside(false);
                mloading.setIcon(R.mipmap.ic_launcher);
                mloading.show();

                PhoneAuthProvider.getInstance().verifyPhoneNumber(
                        getPhoneNumber,        // Phone number to verify
                        60,                 // Timeout duration
                        TimeUnit.SECONDS,   // Unit of timeout
                        this,               // Activity (for callback binding)
                        mcallBacks);
            }
    }

    mcallBacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
        @Override
        public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
            signInWithPhoneAuthCredential(phoneAuthCredential);
        }

        @Override
        public void onVerificationFailed(FirebaseException e) {

            Toast.makeText(PhoneLogin.this, "Wrong Or Invalid Phone Number...", Toast.LENGTH_SHORT).show();
            btn_phone.setVisibility(View.VISIBLE);
            et_check_phone_number.setVisibility(View.VISIBLE);
            et_verify_code.setVisibility(View.INVISIBLE);
            btn_verify.setVisibility(View.INVISIBLE);
            if (e instanceof FirebaseAuthInvalidCredentialsException) {
                Toast.makeText(getBaseContext(), "Invalid Request " + e.toString(), Toast.LENGTH_SHORT).show();
            } else if (e instanceof FirebaseTooManyRequestsException) {
                Toast.makeText(getBaseContext(), "The SMS quota for the project has been exceeded " + e.toString(), Toast.LENGTH_SHORT).show();
            }


        }
        @Override
        public void onCodeSent(String verificationId,
                               PhoneAuthProvider.ForceResendingToken token) {
            // Save verification ID and resending token so we can use them later
            mVerificationId = verificationId;
            mResendToken = token;
            Toast.makeText(PhoneLogin.this, "Code Sent Please Check Your SMS...", Toast.LENGTH_SHORT).show();
            btn_phone.setVisibility(View.INVISIBLE);
            et_check_phone_number.setVisibility(View.INVISIBLE);
            et_verify_code.setVisibility(View.VISIBLE);
            btn_verify.setVisibility(View.VISIBLE);

        }
    };
}




private void VerifyPhoneNumber() {
    getVerifactionCode = et_verify_code.getText().toString();
    if (TextUtils.isEmpty(getVerifactionCode)){
        Toast.makeText(this, "Please Enter The Code Sent To Your SMS...", Toast.LENGTH_SHORT).show();
    }else{
        mloading.setTitle("Checking Your Verification code ");
        mloading.setMessage("Ill Be Back In A Jiffy...");
        mloading.setCanceledOnTouchOutside(false);
        mloading.setIcon(R.mipmap.ic_launcher);
        mloading.show();
        PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, getVerifactionCode);
        signInWithPhoneAuthCredential(credential);
    }

}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {

                     mloading.dismiss();
                        Toast.makeText(PhoneLogin.this, "Login Successful...", Toast.LENGTH_SHORT).show();
                        Intent phoneloginIntent  =new Intent (getBaseContext(),Home_Screen.class);
                        phoneloginIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        startActivity(phoneloginIntent);
                        finish();
                    } else {
                        String mesage = task.getException().toString();
                        Toast.makeText(PhoneLogin.this, "Error: " + mesage, Toast.LENGTH_SHORT).show();
                    }
                }
            });
}

The "+44" I added trying to see if I was entering the wrong phone number. I tried it by adding the +44 manually into the edit text of the app first and that gave the same error.

Edit

So I've removed the line inside the Auth provider that asked if the number was larger than 9 digits as it wasn't working. Also I ran a log to see if it capturing the phone number correctly.

Log.i("Verify_Phone_Number",getPhoneNumber);
 2019-07-16 14:15:30.585 32055-32055/studios.p9p.chatomatic.chat_o_matic I/Verify_Phone_Number: +447******100 and it returns correctly 

Edit 2

So on further testing if I click btn_phone before entering the phone number it works correctly, but if I simply add the phone number to the edit test first then press thebtn_phone it crashes with the above message in logcat.


Solution

  • Ok so the way i solved this problem was to move the mcallbacks to the on create section of code. as shown below

    setContentView(R.layout.activity_phone__login);
        mAuth = FirebaseAuth.getInstance();
        InitVariables();
        AddPhoneNumberButtons();
    
        mcallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
                signInWithPhoneAuthCredential(phoneAuthCredential);
            }
    
            @Override
            public void onVerificationFailed(FirebaseException e) {
    
                Toast.makeText(getBaseContext(), "Wrong Or Invalid Phone Number...", Toast.LENGTH_SHORT).show();
                AddPhoneNumberButtons();
                if (e instanceof FirebaseAuthInvalidCredentialsException) {
                    Toast.makeText(getBaseContext(), "Invalid Request " + e.toString(), Toast.LENGTH_SHORT).show();
                } else if (e instanceof FirebaseTooManyRequestsException) {
                    Toast.makeText(getBaseContext(), "The SMS quota for the project has been exceeded " + e.toString(), Toast.LENGTH_SHORT).show();
                }
    
    
            }
            @Override
            public void onCodeSent(String verificationId,
                                   PhoneAuthProvider.ForceResendingToken token) {
                // Save verification ID and resending token so we can use them later
                verificationid = verificationId;
                mresendtoken = token;
                Toast.makeText(getBaseContext(), "Code Sent Please Check Your SMS...", Toast.LENGTH_SHORT).show();
                AddVerifyButtons();
    
            }
        };