Rid*_*dhi 6 android firebase firebase-authentication
我正在使用 firebase 电话身份验证来验证电话号码。但是,当我尝试切换任何其他应用程序或在进程进行的过程中(即在进程开始和结束之间)按下主页按钮时,会出现问题。即使 OTP 正确且时间未过期,它也始终显示FirebaseAuthInvalidCredentialsException以下消息。
短信代码已过期。请重新发送验证码以重试。
以前,我发现当活动在过程中暂停并恢复时,身份验证过程(验证 OTP 或发送 OTP)停止并且不会恢复。因此,为此,我手动启动了该过程。现在,该过程开始但它总是返回上述异常。
通过使用resumeProcess()on Resume 中的方法。现在,receiveOTP()工作正常。但是OTP的验证仍然存在问题。(正如上面所解释的)。
我正在使用对话框进行电话身份验证。
我为电话身份验证和问题编写的代码如下。
手动恢复在暂停时停止的过程。我resumeProcess()在onResume().
在片段的 onResume()
@Override
public void onResume() {
super.onResume();
if (phoneAuthDialog != null && phoneAuthDialog.isShowing()) {
phoneAuthDialog.resumeProcess();
}
}
Run Code Online (Sandbox Code Playgroud)
而且,在对话...
public void resumeProcess(){
if(isReceivingOtpSms){
receiveOtp(phoneNumber,null);
}
if(isVerifyingOtp){
verifyOtp();
}
}
Run Code Online (Sandbox Code Playgroud)
用于接收 OTP。
private void receiveOtp(String phoneNumber,PhoneAuthProvider.ForceResendingToken forceResendingToken) {
if (connectionDetector != null && connectionDetector.isConnectingToInternet()) {
setPhoneVerificationCallback();
isReceivingOtpSms =true;
showProgress();
//for receiving otp for the first time
if(forceResendingToken==null){
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
activity, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
}
//for resending otp
else {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
activity, // Activity (for callback binding)
mCallbacks, // OnVerificationStateChangedCallbacks
forceResendingToken);
}
} else
showToast(activity, Constants.MESSAGE_NO_CONNECTION);
}
Run Code Online (Sandbox Code Playgroud)
该setPhoneVerificationCallback()方法用于处理验证回调。
private void setPhoneVerificationCallback() {
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
hideProgress(); //to hide progressbar.
isReceivingOtpSms=false;
//some ui process....
verifyCredentials(phoneAuthCredential);
}
@Override
public void onCodeAutoRetrievalTimeOut(String s) {
super.onCodeAutoRetrievalTimeOut(s);
}
@Override
public void onVerificationFailed(FirebaseException e) {
e.printStackTrace();
hideProgress();
isReceivingOtpSms=false;
if (e instanceof FirebaseNetworkException) {
showToast(activity, activity.getString(R.string.err_noconnection_message));
} else if (e instanceof FirebaseAuthInvalidCredentialsException) {
e.printStackTrace();
showToast(activity, "Incorrect phone number format. Check your mobile number and country code twice.");
} else {
showToast(activity, e.getMessage());
}
}
@Override
public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(verificationId, forceResendingToken);
hideProgress();
isReceivingOtpSms=false;
PhoneAuthDialogRefactored.this.verificationId = verificationId;
PhoneAuthDialogRefactored.this.forceResendingToken = forceResendingToken;
//some ui process ...
showToast(activity, "code sent to your number");
}
};
}
Run Code Online (Sandbox Code Playgroud)
该verifyOTP()方法
private void verifyOtp() {
String otp = etOtp.getText().toString().trim();
if (otp.length() == 6) {
if (connectionDetector != null && connectionDetector.isConnectingToInternet()) {
if (verificationId != null) {
Log.e("Verification ID : ", verificationId);
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, otp.trim());
verifyCredentials(credential);
} else {
showToast(activity, "Please wait for a while! the code is not sent yet.");
}
} else {
showToast(activity, activity.getString(R.string.err_noconnection_message));
}
} else {
errOtp.setVisibility(View.VISIBLE);
errOtp.setText(activity.getString(R.string.err_required));
}
}
Run Code Online (Sandbox Code Playgroud)
该verifyCredentials方法验证 OTP 是否正确。
private void verifyCredentials(PhoneAuthCredential credential) {
isVerifyingOtp=true;
showProgress();
if (activity != null) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(activity, task -> {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
hideProgress();
isVerifyingOtp=false;
//some ui process...
} else {
// Sign in failed, display a message and update the UI
hideProgress();
isVerifyingOtp=false;
Log.w("Phone authentication", "signInWithCredential:failure", task.getException());
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
Exception exception=task.getException();
if(exception.getMessage().equals("The sms code has expired. Please re-send the verification code to try again.")){
showToast(activity,exception.getMessage());
errOtp.setVisibility(View.VISIBLE);
errOtp.setText(activity.getString(R.string.err_expired_code));
}
else {
errOtp.setVisibility(View.VISIBLE);
errOtp.setText(activity.getString(R.string.err_wrong_otp));
}
}
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
请帮助我解决这个问题,如果我的问题不清楚,请随时提问。主要问题是
当即使 OTP 正确且时间未过期。它仍然显示代码已过期。只有在我们暂停并恢复活动时才会发生这种情况。在一个过程中。(我的意思是在一个过程的中间,验证过程已经开始,但在它完成验证过程(成功或失败)之前,我按下切换到另一个应用程序并返回到应用程序)
小智 1
@Riddhi我认为问题在于您在验证时发送的verificationId。代码看起来不错。我之前发送验证ID时遇到了同样的问题。
public class OtpVerificationActivity extends AppCompatActivity implements View.OnClickListener {
EditText mobileNumber,otpText;
Button sendOtp,verifyOtp;
FirebaseAuth mAuth;
String codeSent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_otp_verification);
mobileNumber = findViewById(R.id.mobileNumber);
otpText = findViewById(R.id.otpText);
sendOtp = findViewById(R.id.sendOtp);
verifyOtp = findViewById(R.id.verifyOtp);
sendOtp.setOnClickListener(this);
verifyOtp.setOnClickListener(this);
mAuth = FirebaseAuth.getInstance();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.sendOtp:
sendVerificationCode();
break;
case R.id.verifyOtp:
verifyCodeSent();
break;
}
}
private void verifyCodeSent() {
String code = otpText.getText().toString();
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeSent,code);
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()) {
// Sign in success, update UI with the signed-in user's information
Log.d("verifyCode", "signInWithCredential:success");
Toast.makeText(OtpVerificationActivity.this, "Successful", Toast.LENGTH_SHORT).show();
//FirebaseUser user = task.getResult().getUser();
// ...
} else {
// Sign in failed, display a message and update the UI
Log.w("verifyCode", "signInWithCredential:failure", task.getException());
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
Toast.makeText(OtpVerificationActivity.this, ""+task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
});
}
private void sendVerificationCode() {
String phoneNumber = mobileNumber.getText().toString();
if (phoneNumber.isEmpty()){
mobileNumber.setError("mobile number cannot be empty");
mobileNumber.requestFocus();
}
if (phoneNumber.length() < 10){
mobileNumber.setError("Please enter a valid phone");
mobileNumber.requestFocus();
}
PhoneAuthProvider.getInstance().verifyPhoneNumber(
"+91" + phoneNumber, // Phone number to verify (I hardcoded it only for Indian Mobile numbers).
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks);
}
PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
}
@Override
public void onVerificationFailed(FirebaseException e) {
}
@Override
public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
codeSent = s;
}
};
}
Run Code Online (Sandbox Code Playgroud)
我希望这个对你有用。您检查完此代码后可以回复我吗?
| 归档时间: |
|
| 查看次数: |
3715 次 |
| 最近记录: |