Firebase链接到电话的电子邮件:如果不进行验证,则无法创建PhoneAuthCredential

时间:2019-05-01 09:37:08

标签: java android firebase firebase-authentication

自从我上周更新Firebase以来,我的Phone Verification一直在工作。从那时起,我面临的问题是,在我将用户电子邮件连接到电话号码的链接过程中,该链接不再起作用: java.lang.IllegalArgumentException:如果没有verifyProof,sessionInfo或临时证明,则无法创建PhoneAuthCredential。 我看到有些用户遇到相同的问题,但没人解决。

我试图重写整个代码,但问题仍然存在。 Firebase在链接过程中是否进行了更改? 如我在Firebase链接文档中所见,有关电话号码链接的部分已删除。

我的代码有问题吗或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...";



                });
    }



    }

2 个答案:

答案 0 :(得分:0)

当Firebase通过检测发送到电话的短信代码自动验证电话号码时,会调用

onVerificationCompleted。 我认为您应该重新格式化代码,以仅在此处使用凭证,或者通过结合用户输入的代码和VerificationId手动生成凭证。而不是两者兼而有之。 另外,您无需登录即可使用电话凭据登录

我的意思是应该改成这样,

private void linkWithCredential(final PhoneAuthCredential credential) {
        mAuth.getCurrentUser().linkWithCredential(credential).addOnComplete.......{
            onComplete(....) {
                .....
                //signInWithPhoneCredential(credential);
                // You Already signed in. No need. Just update the ui with the user info
    }

https://firebase.google.com/docs/auth/android/account-linking

答案 1 :(得分:0)

此处介绍如何使用Firebase文档中的Firebase电话身份验证
https://firebase.google.com/docs/auth/android/phone-auth
和链接身份验证提供程序
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:在链接电话号码验证之前,您需要重新验证电子邮件验证。
单击此链接以重新验证
https://firebase.google.com/docs/auth/android/manage-users#re-authenticate_a_user