I'm using the createAccount() method from Firebase Authentication and I have attached two listeners :
addOnSuccessListenerand addOnFailureListener
When I'm creating an account and at the same time loosing the internet connection, the account is successfully created (I can see it in Firebase console) whereas the
onFailurelistener is called.Also, when I'm creating this account, I am saving a User object in Firestore with a
Task<Void>called asynchronously from the auth method. The problem is that this user is never created in Firestore Database because of the previous failure but has got an authentication account anyway.
The result is that the user is able to log in but does not exist in the database and thus all his fields are null.
I could not find any rollbacks on the Firebase auth methods, so for now on I am logging in the user and at this time checking if a User object with the same email exists in the database... But I don't think this is a good approach
So how to handle a such scenario ?
EDIT : code I'm using
firebaseAPI.createAccount(email, password, userName).addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
System.out.println("onSuccess: the firebase user is not null.");
final FirebaseUser currentUser = authResult.getUser();
if (currentUser != null) {
// Send an email to verify the new account created
currentUser.sendEmailVerification()
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
System.out.println("onSuccess: email verification has been sent.");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
System.out.println("onFailure: failed to send the emailVerification.");
System.out.println("onFailure: " + e.getMessage());
}
});
System.out.println("onComplete: registering the username.");
// Update the display name of the firebaseUser object
final UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder().setDisplayName(userName).build();
currentUser.updateProfile(profileUpdates).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
System.out.println("onFailure: " + e.getMessage());
System.out.println("onFailure: failed to update the user display name.");
}
}).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
System.out.println("onSuccess: display name updated.");
System.out.println("onSuccess: writing batch.");
String uid = currentUser.getUid();
// Fields to register in Firestore Database.
final User userToRegister = new User(uid, userName, email, birthDate, lastName, firstName);
// Register the Username in Firestore Database & the user as the same time to rollback everything if something happens.
firebaseAPI.createUser(userToRegister, uid).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
System.out.println("onSuccess: logging the user in.");
onSignUpSuccess(userToRegister);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
System.out.println("onFailure: " + e.getMessage());
System.out.println("onFailure: sending error to the activity");
if (e.getMessage().contains("offline") || e.getMessage().contains("internal error")) {
onSignUpError(SignUpErrorType.INTERNET_FAILED);
}
else {
onSignUpError(SignUpErrorType.GENERIC_ERROR);
}
deleteUser(currentUser);
}
}).addOnCanceledListener(new OnCanceledListener() {
@Override
public void onCanceled() {
System.out.println("onCanceled: batch canceled.");
onSignUpError(SignUpErrorType.GENERIC_ERROR);
deleteUser(currentUser);
}
});
}
});
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
System.out.println("onFailure: " + e.getMessage());
if (e.getMessage().contains("internal error") || e.getMessage().contains("network error")) {
// equals("An internal error has occurred. [ 7: ]")
System.out.println("onFailure: sending error to the activity");
onSignUpError(SignUpErrorType.INTERNET_FAILED);
} else if (e.getMessage().contains("mail")){
System.out.println("onFailure: sending error to the activity");
System.out.println("onFailure: error is : " + e.getMessage());
onSignUpError(SignUpErrorType.EMAIL_ALREADY_TAKEN);
}
else {
System.out.println("onFailure: error is : " + e.getMessage());
onSignUpError(SignUpErrorType.GENERIC_ERROR);
}
}
});
Error in logcat :
I/System.out: onFailure: A network error (such as timeout, interrupted connection or unreachable host) has occurred.