我正在使用电子邮件/密码和电话方法注册用户。
申请程序如下
使用PhoneAuthCredential登录用户>使用输入的电子邮件和密码通过EmailCredential链接创建的用户>发送电子邮件验证>数据库条目
public class Sign_Up_page extends AppCompatActivity {
private String TAG = "Sign_Up_page";
// UI Widgets.
private View sign_up_btn;
// Firebase
private FirebaseAuth firebaseAuth;
private DatabaseReference reference;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
private PhoneAuthProvider.ForceResendingToken mResendToken;
private FirebaseAuth.AuthStateListener authListener;
private UserPojo userPojo;
private String mVerificationId = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign__up_page);
firebaseAuth = FirebaseAuth.getInstance();
authListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null) {
Toast.makeText(Sign_Up_page.this, "user is null", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(Sign_Up_page.this, "user not null", Toast.LENGTH_LONG).show();
}
}
};
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
signInWithPhoneAuthCredential(credential);
}
@Override
public void onVerificationFailed(FirebaseException e) {
}
@Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
mResendToken = token;
}
};
}
@Override
public void onClick(View v) {
super.onClick(v);
if (v == sign_up_btn) {
firebaseAuth.fetchSignInMethodsForEmail(userEmail).addOnCompleteListener(new OnCompleteListener<SignInMethodQueryResult>() {
@Override
public void onComplete(@NonNull Task<SignInMethodQueryResult> task) {
if (task.isSuccessful()) {
SignInMethodQueryResult result = task.getResult();
List<String> signInMethods = result != null ? result.getSignInMethods() : null;
if (signInMethods != null && signInMethods.size() == 0) {
startPhoneNumberVerification(userPhone);
verifyPhoneDialog();
}
}
}
});
}
}
private void signInWithPhoneAuthCredential(final PhoneAuthCredential credential) {
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
if (task.getResult() != null) {
if (task.getResult().getAdditionalUserInfo().isNewUser()) {
AuthCredential emailCredential = EmailAuthProvider.getCredential(userEmail, userPass);
Toast.makeText(Sign_Up_page.this, "Signedin with phone", Toast.LENGTH_LONG).show();
linkUserCredentials(emailCredential);
} else {
firebaseAuth.signOut();
Toast.makeText(THIS, "This Phone no. is already registered with different account", Toast.LENGTH_SHORT).show();
}
}
}
}
});
}
private void linkUserCredentials(final AuthCredential credential) {
firebaseAuth.getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(Sign_Up_page.this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
if (task.getResult() != null) {
FirebaseUser user = task.getResult().getUser();
Toast.makeText(Sign_Up_page.this, "credential linked", Toast.LENGTH_LONG).show();
// null current user was causing the account to create in Firebase Auth
// but no entry in Database so here I'm using user instance returned on
// linkCredentialSuccess for furthur use instead of "firebaseAuth.getCurrentUser()" to prevent that issue
sendVerificationEmail(user);
}
} else {
firebaseAuth.getCurrentUser().delete();
}
}
});
}
private void sendVerificationEmail(final FirebaseUser createdUser) {
if (firebaseAuth.getCurrentUser() != null) {
firebaseAuth.getCurrentUser().sendEmailVerification()
.addOnCompleteListener(this, new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
Toast.makeText(Sign_Up_page.this, "email verification Op complete", Toast.LENGTH_LONG).show();
createUser(emailDelivery, createdUser);
}
});
}
}
private void createUser(final boolean emailDelivery, final FirebaseUser createdUser) {
reference = FirebaseDatabase.getInstance().getReference("users");
Toast.makeText(Sign_Up_page.this, "Creating user", Toast.LENGTH_LONG).show();
userPojo = new UserPojo();
userPojo.setValues(...);
String uid = "";
if (createdUser != null) {
uid = createdUser.getUid();
}
if (firebaseAuth.getCurrentUser() == null) {
AuthCredential emailCredential = EmailAuthProvider.getCredential(userEmail, userPass);
if (createdUser != null) {
createdUser.reauthenticate(emailCredential).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(Sign_Up_page.this, "user reAuthenticated", Toast.LENGTH_LONG).show();
}
}
});
}
}
if (!uid.equals("")) {
UserProfileChangeRequest userProfile = new UserProfileChangeRequest.Builder()
.setDisplayName(userName).build();
createdUser.updateProfile(userProfile);
userPojo.setUid(uid);
final String path = "" + FirebaseDatabase.getInstance().getReference("users").child(uid);
reference.child(uid).setValue(userPojo).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
startActivity(new Intent(Sign_Up_page.this, Home_Screen.class));
} else {
createdUser.delete();
AlertDialog.Builder DbEntryFailDialog = new AlertDialog.Builder(Sign_Up_page.this);
DbEntryFailDialog.setTitle("Error")
.setMessage("Error" + task.getException().getMessage()
+ "\n\nentry url is " + path)
.setPositiveButton("Ok", null)
.show();
Toast.makeText(Sign_Up_page.this, "Error occurred creating account when Db entry fail, Please try again", Toast.LENGTH_LONG).show();
}
}
});
} else {
if (createdUser != null) {
createdUser.delete();
}
}
}
@Override
protected void onStart() {
super.onStart();
firebaseAuth.addAuthStateListener(authListener);
}
@Override
protected void onStop() {
super.onStop();
firebaseAuth.addAuthStateListener(authListener);
}
}
现在问题出在10次尝试中就有1次 firebaseAuth.getCurrentUser()与电子邮件凭据链接后变为空
我添加了authStateListener来跟踪用户身份验证状态中的更改
这是屏幕截图
of steps
这是我的 users 表
的数据库写入规则"users":{
"$uid":{
".write": "auth.uid != null && newData.exists()",
},
".indexOn": "role"
}
现在我可以处理空用户或数据库故障,但是我想知道并防止导致此问题的原因
我做错了什么,或者这是一个firebase错误...?