Firebase link email to phone: Cannot create PhoneAuthCredential without verificationProof

Los Kayos :

So I had my Phone Verify working since I updated my Firebase last week. Since then I'm facing the problem that in my linking process where I'm connecting the users email to the phone number doesn't work anymore: java.lang.IllegalArgumentException: Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, ortemprary proof. I've seen some users with the same problem but nobody with a solution.

I tried to rewrite the whole Code but the problem is still there. Has Firebase changed something in the linking process? As I have seen in the Firebase Linking Documentation, the section about Phone Number linking was removed.

Is something wrong with my code or is it a problem with firebase?

Firebase Versions I'm using:

implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.google.firebase:firebase-messaging:17.6.0'
implementation 'com.google.firebase:firebase-perf:16.2.5'
implementation 'com.android.support:support-compat:28.0.0'
implementation 'com.google.firebase:firebase-auth:16.2.1'
implementation 'com.google.firebase:firebase-storage:16.1.0'
   @Override
   protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.user_phone_verify);
   Log.e("PhoneVerify","Start");

        mAuth = FirebaseAuth.getInstance();

        editTextCode = findViewById(R.id.editTextCode);
        editTextPhone = findViewById(R.id.editTextPhone);

        Bundle extras = getIntent().getExtras();
        if (extras !=null) {
            final String phone = extras.getString("phone");
            Log.e("Phone(Extras):",phone);
            editTextPhone.setText(phone);
            sendVerificationCode(phone);
        }


        findViewById(R.id.buttonGetVerificationCode).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String phone = editTextPhone.getText().toString().trim();
                if (phone.isEmpty() || phone.length() < 10) {
                    editTextPhone.setError("Phone number error");
                    editTextPhone.requestFocus();
                    return;
                }

                 sendVerificationCode(phone);
            }
        });


        findViewById(R.id.buttonSignIn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                verifyVerificationCode(editTextCode.getText().toString());
            }
        });
    }


    private void sendVerificationCode(String phonenumber) {
        String phone = "+14" + phonenumber;
        Log.e("sendVerificationCode",phone);
        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                phone,        // Phone number to verify
                60,                 // Timeout duration
                TimeUnit.SECONDS,   // Unit of timeout
                this,               // Activity (for callback binding)
                mCallbacks);        // OnVerificationStateChangedCallbacks
    }



    PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

        @Override
        public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {

             //Getting the code sent by SMS
            final String code = phoneAuthCredential.getSmsCode();

            if (code != null) {
                editTextCode.setText(code);
                //verifying the code
                verifyVerificationCode(code);
                Log.e("onVerificationCompleted",code);
            }

        }

        @Override
        public void onVerificationFailed(FirebaseException e) {
            Log.e("onVerificationFailed", String.valueOf(e));

        }

        @Override
        public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
            super.onCodeSent(s, forceResendingToken);
            Log.e("onCodeSent", "Code Sent");
            codeSent = s;
            PhoneAuthProvider.ForceResendingToken mResendToken = forceResendingToken;
        }
    };



    private void verifyVerificationCode(String code) {
        //creating the credential
        try {

            PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeSent, code);
            linkWithCredential(credential,code);

        } catch (Exception e) {
            Log.e("Exception", String.valueOf(e));
        }

        Log.e("VerifyCode CHECKP",code);
        //signing the user

    }

    private void linkWithCredential(final AuthCredential credential, final String code) {
        mAuth.getCurrentUser().linkWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                Log.e("Linking Phone to Email","Successfull");

                try {

                    PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeSent, code);
                    signInWithPhoneAuthCredential(credential);

                } catch (Exception e) {
                    Log.e("Exception", String.valueOf(e));
                }

            }
        });
    }


    private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(PhoneVerify.this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            //verification successful we will start the profile activity

                            Log.e("FINAL LINK","DONE");


                        } else {
                            //verification unsuccessful.. display an error message

                            String message = "Somthing is wrong, we will fix it soon...";



                });
    }



    }
flx_h :

Here how to use Firebase Phone Authentication from Firebase docs
https://firebase.google.com/docs/auth/android/phone-auth
and linking Authentication provider
https://firebase.google.com/docs/auth/android/account-linking

//please notice, mCallback.onVerificationCompleted will automatically called 
//if verification code already send to your phone 
//(Maybe not called in some case)
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    @Override
    public void onVerificationCompleted(PhoneAuthCredential credential) {
        linkPhoneAuthToCurrentUser(credential);
    }

    @Override
    public void onVerificationFailed(FirebaseException e) {
        //show error
    }
    @Override
    public void onCodeSent(String verificationId,
                           PhoneAuthProvider.ForceResendingToken token) {
        //save id and token in case you need to resend verification code
    }
};

//call this to send verification code
//parameter include country code
private void sendVerificationCode(String phonenumber) {
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
            phonenumber,        // Phone number to verify
            60,                 // Timeout duration
            TimeUnit.SECONDS,   // Unit of timeout
            this,               // Activity (for callback binding)
            mCallbacks);        // OnVerificationStateChangedCallbacks
}

//link auth with credential
private void linkPhoneAuthToCurrentUser(PhoneAuthCredential credential) {
    FirebaseAuth.getInstance().getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    //link auth success update ui
                } else {
                    //link auth failed update ui
                }
            }
        });
}
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.user_phone_verify);

   //init view 

   //get phone number
   String phoneNumb = "Add Your Phone Number Here"
   sendVerificationCode(phoneNumb)

   //if mCallback not called, 
   //use this button to sign in with manual input verification code
   btnSignIn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //get verification id from mCallback.onCodeSent
            //get verificationCode manually from edittext 
            PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, verificationCode);
            linkPhoneAuthToCurrentUser(credential);
        }
    });
}

PS : you need to re-authenticate your email authentication before link phone number authentication.
Follow this link to re-authenticate
https://firebase.google.com/docs/auth/android/manage-users#re-authenticate_a_user

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=166493&siteId=1