【发布时间】:2021-01-15 17:00:49
【问题描述】:
我正在构建一个应用程序,要求用户填写注册屏幕的详细信息。一旦他们填写了所有详细信息并验证了详细信息,我就允许他们输入他们的电子邮件 ID。验证电子邮件 ID 后(1. 空白电子邮件 2. 无效电子邮件 ID 3. 通过 Firebase 检查现有电子邮件 ID)然后应用程序将为用户创建电子邮件(使用电子邮件密码)。创建电子邮件有 3 个阶段。
- A.电子邮件创建本身和
- 乙。向用户发送验证电子邮件。
- C.等到用户验证电子邮件。
验证电子邮件后,我允许用户输入手机号码。在填写移动验证时会发生(1. 空白移动 2. 无效移动号 3. 通过 Firebase 进行现有移动检查)。如果验证结果是肯定的,我要求他们通过 OTP(新活动)验证手机。经过OTP验证,最后,我将所有用户的数据存储到firebase(密码除外)。
我的实际问题在这里。我希望用户通过电话 OTP 流程或电子邮件密码流程登录。目前,我无法链接用户的电子邮件和电话,因为 Firebase 正在考虑作为 2 个帐户。在谷歌上,我知道我必须使用LinkWithCredential 选项进行链接。但是,它不起作用...
这是我的VerifyOTP 代码,用于进行电话身份验证...
public class VerifyOTP extends AppCompatActivity {
@BindView(R.id.PinViewUser)
PinView PinViewUser;
@BindView(R.id.btnVerify)
Button btnVerify;
@BindView(R.id.btnGetOTP)
Button btnGetOTP;
@BindView(R.id.btnResend)
Button btnResend;
@BindView(R.id.txtCodeVerificationText)
TextView txtCodeVerificationText;
@BindView(R.id.Verificationlabel)
TextView Verificationlabel;
@BindView(R.id.txtNoteToUser)
TextView txtNoteToUser;
FirebaseAuth mAuth;
AuthCredential emailCredential;
String UserPhoneNo, CodeBySystem, PhNoThroughSignUp, PhNoThroughForgotPassword, ForwardEmailToNextClass, GetCredEmail, GetCredPass;
PhoneAuthProvider.ForceResendingToken mResendToken;
private static final String TAG = "AnonymousAuth";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RunAppOnFullScreenMode();
setContentView(R.layout.activity_verify_o_t_p);
ButterKnife.bind(this);
//get Ph No & Other Details from SignupLayout
PhNoThroughSignUp = getIntent().getStringExtra(ReUsuableCode.CustomMobileNo);
GetCredEmail = getIntent().getStringExtra("CredEmail");
GetCredPass = getIntent().getStringExtra("CredPass");
emailCredential = EmailAuthProvider.getCredential(GetCredEmail, GetCredPass);
//get Ph No from ForgotPassword
PhNoThroughForgotPassword = getIntent().getStringExtra("FPMobile");
if (PhNoThroughSignUp == null) {
UserPhoneNo = PhNoThroughForgotPassword;
} else {
UserPhoneNo = PhNoThroughSignUp;
}
Toast.makeText(this, "Email: " + GetCredEmail + "Password: " + GetCredPass + "Phone: " + UserPhoneNo, Toast.LENGTH_LONG).show();// this is working
txtCodeVerificationText.setText("Click On Get OTP Button to Get the OTP on the Mentioned Phone No\n\n Note: Standard SMS charges May Apply");
Log.d(TAG, "DetailsCollected");
// Initialize Firebase Auth
mAuth = FirebaseAuth.getInstance();
//Send OTPCode to User
btnGetOTP.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SendVerificationCodeToUser(UserPhoneNo);
Log.d(TAG, "Verification Code Sent");
txtNoteToUser.setVisibility(View.VISIBLE);
txtCodeVerificationText.setText("Enter the One Time Password received on\n " + UserPhoneNo);
Toast.makeText(VerifyOTP.this, "OTP Initiated!! Wait For Auto Verification of OTP", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
btnVerify.setVisibility(View.VISIBLE);
}
}, 10000); // where 1000 is equal to 1 sec (1 * 1000)
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
btnResend.setVisibility(View.VISIBLE);
}
}, 60000); // where 1000 is equal to 1 sec (1 * 1000)
}
});
//ReSend OTPCode to User
btnResend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resendVerificationCode(UserPhoneNo, mResendToken);
txtCodeVerificationText.setText("Resent verification code to " + UserPhoneNo + "\n\n Note: Standard SMS charges May Apply");
btnResend.setVisibility(View.INVISIBLE);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
btnResend.setVisibility(View.VISIBLE);
}
}, 60000); // where 1000 is equal to 1 sec (1 * 1000)
}
});
//Manual Click on VerifyButton
btnVerify.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String code = PinViewUser.getText().toString();
if (ReUsuableCode.fieldisEmpty(code)) {
PinViewUser.setError("Field is Empty");
} else {
VerifyCode(CodeBySystem, code);
}
}
});
}
//======================================= Other Private Codes==================
private void SendVerificationCodeToUser(String phNo) {
PhoneAuthOptions options =
PhoneAuthOptions.newBuilder(mAuth)
.setPhoneNumber(phNo) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this) // Activity (for callback binding)
.setCallbacks(mCallbacks) // OnVerificationStateChangedCallbacks
.build();
PhoneAuthProvider.verifyPhoneNumber(options);
}
public void linkCredential(AuthCredential credential) {
mAuth.getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "linkWithCredential:success");
FirebaseUser user = task.getResult().getUser();
Toast.makeText(VerifyOTP.this, "linkWithCredential:success", Toast.LENGTH_SHORT).show();
if (PhNoThroughSignUp == null) {
Intent GoToAnotherLayout1 = new Intent(VerifyOTP.this, SetPassword.class);
ForwardEmailToNextClass = getIntent().getStringExtra("FEmail");
GoToAnotherLayout1.putExtra("FEmail", ForwardEmailToNextClass);
startActivity(GoToAnotherLayout1);
finish();
} else {
Intent GoToAnotherLayout1 = new Intent(VerifyOTP.this, Retailer_SignUP.class);
GoToAnotherLayout1.putExtra(ReUsuableCode.MobileRegistration, "Mobile Validation Successful");
setResult(RESULT_OK, GoToAnotherLayout1);
finish();
}
} else {
Log.w(TAG, "linkWithCredential:failure", task.getException());
Toast.makeText(VerifyOTP.this, "linkWithCredential:failure" + task.getException().toString(), Toast.LENGTH_SHORT).show();
}
}
});
}
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks =
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onCodeSent(@NonNull String s, @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
// Save verification ID and resending token so we can use them later
CodeBySystem = s;
mResendToken = forceResendingToken;
Log.d(TAG, "OnCode Completed");
}
@Override
public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
Log.d(TAG, "On Verification start");
Toast.makeText(VerifyOTP.this, "OTP Verification Successful", Toast.LENGTH_SHORT).show();
String code = phoneAuthCredential.getSmsCode();
if (code != null) {
PinViewUser.setText(code);
VerifyCode(CodeBySystem, code);
Log.d(TAG, "Pre Link State");
linkCredential(emailCredential);
Log.d(TAG, "Post Link State");
}
}
@Override
public void onVerificationFailed(@NonNull FirebaseException e) {
Log.d(TAG, "Verification Failed");
if (e instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(VerifyOTP.this, "Failed to Verify!! Try After Some Time...", Toast.LENGTH_SHORT).show();
return;
} else if (e instanceof FirebaseTooManyRequestsException) {
Toast.makeText(VerifyOTP.this, "Too Many Attempts!! Try After Some Time...", Toast.LENGTH_SHORT).show();
return;
} else {
Toast.makeText(VerifyOTP.this, "Some Other Error Occured...", Toast.LENGTH_SHORT).show();
return;
}
}
};
private void VerifyCode(String verificationId, String code) {
PhoneAuthCredential Credential = PhoneAuthProvider.getCredential(verificationId, code);
Log.d(TAG, "Verified Code");
}
// [START resend_verification]
private void resendVerificationCode(String phoneNumber,
PhoneAuthProvider.ForceResendingToken token) {
PhoneAuthOptions options =
PhoneAuthOptions.newBuilder(mAuth)
.setPhoneNumber(phoneNumber) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this) // Activity (for callback binding)
.setCallbacks(mCallbacks) // OnVerificationStateChangedCallbacks
.setForceResendingToken(token) // ForceResendingToken from callbacks
.build();
PhoneAuthProvider.verifyPhoneNumber(options);
}
请在我失踪的地方指导我。如何为用户创建一个帐户?
【问题讨论】:
标签: android firebase-authentication