I am using OTP verification for my Android device, and while everything works and I can receive the OTP, the browser reCAPTCHA occurs, and I am taken to the next stage in my app. This doesn't seem like a problem, but the inner code of "onVerificationCompleted" does not execute. In my app, the steps for "onCodeSent" run when it is auto-verified and I am redirected to the OTP filling page. So, a few data statuses are not changed.
Here is my code:
PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
// This callback will be invoked in two situations:
// 1 - Instant verification. In some cases, the phone number can be instantly
// verified without needing to send or enter a verification code.
// 2 - Auto-retrieval. On some devices, Google Play services can automatically
// detect the incoming verification SMS and perform verification without
// user action.
user.updatePhoneNumber(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@androidx.annotation.NonNull Task<Void> task) {
String userId = userID;
Boolean verification = true;
email = getIntent().getStringExtra("email");
User user = new User(name, phone, email, usertype, userId, verification);
UserDB.child("Users").child(userID).setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@androidx.annotation.NonNull Task<Void> task) {
Toast.makeText(user_details_register.this, "Verification Complete. User Data saved", Toast.LENGTH_SHORT).show();
Intent main = new Intent(getApplicationContext(), MainActivity.class);
startActivity(main);
finish();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@androidx.annotation.NonNull Exception e) {
UserDB.child("Users").child(userID).setValue(user);
}
});
progressBar.setVisibility(View.INVISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@androidx.annotation.NonNull Exception e) {
user.updatePhoneNumber(credential);
String userId = userID;
Boolean verification = true;
email = getIntent().getStringExtra("email");
User user = new User(name, phone, email, usertype, userId, verification);
UserDB.child("Users").child(userID).setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@androidx.annotation.NonNull Task<Void> task) {
Toast.makeText(user_details_register.this, "Verification Complete. User Data saved", Toast.LENGTH_SHORT).show();
Intent main = new Intent(getApplicationContext(), MainActivity.class);
startActivity(main);
finish();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@androidx.annotation.NonNull Exception e) {
UserDB.child("Users").child(userID).setValue(user);
}
});
progressBar.setVisibility(View.INVISIBLE);
}
});
}
@Override
public void onVerificationFailed(@NonNull FirebaseException e) {
// This callback is invoked in an invalid request for verification is made,
// for instance, if the phone number format is not valid.
if (e instanceof FirebaseAuthInvalidCredentialsException) {
//Invalid number
Toast.makeText(user_details_register.this, "Please check your number", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.INVISIBLE);
return;
} else if (e instanceof FirebaseTooManyRequestsException) {
String userId = userID;
Boolean verification = false;
email = getIntent().getStringExtra("email");
User user = new User(name, phone, email, usertype, userId, verification);
UserDB.child("Users").child(userID).setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@androidx.annotation.NonNull Task<Void> task) {
Toast.makeText(user_details_register.this, "Verification could not be completed. Please try again later. User Data saved", Toast.LENGTH_SHORT).show();
Intent main = new Intent(getApplicationContext(), MainActivity.class);
startActivity(main);
finish();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@androidx.annotation.NonNull Exception e) {
UserDB.child("Users").child(userID).setValue(user);
}
});
progressBar.setVisibility(View.INVISIBLE);
return;
} else if (e instanceof FirebaseAuthMissingActivityForRecaptchaException) {
// reCAPTCHA verification attempted with null Activity
progressBar.setVisibility(View.INVISIBLE);
return;
}
// Show a message and update the UI
}
@Override
public void onCodeSent(@NonNull String verificationId,
@NonNull PhoneAuthProvider.ForceResendingToken token) {
// The SMS verification code has been sent to the provided phone number, we
// now need to ask the user to enter the code and then construct a credential
// by combining the code with a verification ID.
// Save verification ID and resending token so we can use them later
@NonNull String mVerificationId = verificationId;
PhoneAuthProvider.@NonNull ForceResendingToken mResendToken = token;
String userId = userID;
Boolean verification = false;
email = getIntent().getStringExtra("email");
User user = new User(name, phone, email, usertype, userId, verification);
UserDB.child("Users").child(userID).setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@androidx.annotation.NonNull Task<Void> task) {
Toast.makeText(user_details_register.this, "OTP sent to your number: " + phone, Toast.LENGTH_SHORT).show();
Intent otp_ver = new Intent(getApplicationContext(), OtpVerification.class);
otp_ver.putExtra("OTPBackend", verificationId);
startActivity(otp_ver);
finish();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@androidx.annotation.NonNull Exception e) {
UserDB.child("Users").child(userID).setValue(user);
Intent otp_ver = new Intent(getApplicationContext(), OtpVerification.class);
otp_ver.putExtra("number", phone);
otp_ver.putExtra("OTPBackend", verificationId);
startActivity(otp_ver);
finish();
}
});
progressBar.setVisibility(View.INVISIBLE);
}
};
PhoneAuthOptions options =
PhoneAuthOptions.newBuilder(mAuth)
.setPhoneNumber("+91" + phone.trim()) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(user_details_register.this) // (optional) Activity for callback binding
// If no activity is passed, reCAPTCHA verification can not be used.
.setCallbacks(mCallbacks) // OnVerificationStateChangedCallbacks
.build();
PhoneAuthProvider.verifyPhoneNumber(options);