Я регистрирую пользователей, используя методы электронной почты / пароля и телефона.
Процедура регистрации выглядит следующим образом
Войдите в систему с помощью 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);
}
}
теперь проблема в 1 из 10 попыток firebaseAuth.getCurrentUser () становится недействительным после установления связи с учетными данными электронной почты
I 'мы добавили authStateListener для отслеживания изменений в состоянии аутентификации пользователя
вот скриншот шагов
вот мои правила записи в БД для пользователей таблица
"users":{
"$uid":{
".write": "auth.uid != null && newData.exists()",
},
".indexOn": "role"
}
Теперь я могу справиться с ошибкой нулевого пользователя или БД, но я хочу знать и предотвратить причину этой проблемы
Я сделал что-то не так или это ошибка Firebase ...?