android - Firebase getCurrentUser 在 linkWithCredentials 之后返回 null 有时
问题描述
我正在使用电子邮件/密码和电话方法注册用户。
注册过程如下
使用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()在使用电子邮件凭据链接后变为 null
我添加了 authStateListener 以跟踪用户身份验证状态的变化
这里是
步骤的屏幕截图
这是我的用户表 的数据库写入规则
"users":{
"$uid":{
".write": "auth.uid != null && newData.exists()",
},
".indexOn": "role"
}
现在我可以处理空用户或数据库故障,但我想知道并防止导致这个问题的原因是
我做错了什么,或者这是一个 firebase 错误......?
解决方案
推荐阅读
- php - 一对服务器之间的字符集编码差异
- javascript - 如何仅将子依赖的 lodash 包(babel/core 所需的依赖包)从 lodash@4.17.19 更新到 v4.17.21
- excel - 在 Excel 中连续查找条纹
- scala - 你怎么能得到流开始的迹象?(阿卡)
- grep - GREP 在 InDesign 中查找前面没有句号和空格的大写 T
- arrays - 搜索数组中的元素
- swift - 在 Swift 中合并两个 NSMutableArray
- c - () 优先级最高,为什么会短路?
- haskell - ghci only loads with admin
- vue.js - 如何将这三个组件变成一个多步表单向导