Firebase 将电子邮件链接到手机:未经验证证明,则无法创建电话身份验证凭据



所以我的手机验证工作,因为我上周更新了我的Firebase。从那以后,我面临着一个问题,即在将用户电子邮件连接到电话号码的链接过程中,我不再起作用: java.lang.IllegalArgumentException:如果没有 verificationProof、sessionInfo或临时证明,则无法创建 PhoneAuthCredential。 我见过一些用户遇到同样的问题,但没有解决方案。

我试图重写整个代码,但问题仍然存在。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...";

});
}

}

下面介绍了如何使用 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

当 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

最新更新