FirebaseAuth.signOut后Firestore无法存数据,求技术解决方案
Hey there! I see exactly what's going on here. Your issue stems from how Firebase's asynchronous operations work—let's break it down and fix it.
问题原因
When you call user.save() followed immediately by mAuth.signOut() and finish(), the Firestore set() operation inside save() is asynchronous. That means it starts running in the background, but your code doesn't wait for it to finish before signing out and closing the activity.
Once the activity finishes, the system may terminate any pending background tasks (like your Firestore save) before they complete. That's why you don't see your "Saved" or "Not Saved" logs—those callbacks never get a chance to run.
解决方案
We need to modify your code to wait until the Firestore save operation is fully completed (success or failure) before signing out and finishing the activity. Here's how to do it:
Step 1: Update the save() method to return a Task
First, let's adjust your save() function to return the Task<Void> from Firestore's set() call. This lets us listen for when the save finishes:
public Task<Void> save(){ DocumentReference reference = FirebaseFirestore.getInstance().document("/Clinicas/" + clinic + "/Profissionais/" + id + "/"); Map<String, Object> dataToSave = new HashMap<String, Object>(); dataToSave.put("Name", name); dataToSave.put("email", email); dataToSave.put("clinic", clinic); dataToSave.put("Job", job); return reference.set(dataToSave); }
Step 2: Wait for the save to finish before signing out
Now, in your registUser() method, instead of calling signOut() right after user.save(), we'll add a listener to the returned Task. This ensures we only sign out once the data is saved (or we've handled a failure):
public void registUser() { mAuth = FirebaseAuth.getInstance(); mAuth.createUserWithEmailAndPassword(user.getEmail(), user.getPassword()) .addOnCompleteListener(SignUpUserActivity.this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { Toast.makeText(SignUpUserActivity.this, "Sucesso", Toast.LENGTH_SHORT).show(); user.setId(task.getResult().getUser().getUid()); // Wait for Firestore save to complete before signing out user.save() .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { Log.d("artur", "Saved"); mAuth.signOut(); finish(); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Log.w("artur", "Not Saved", e); // Optional: Show an error toast to the user here // Toast.makeText(SignUpUserActivity.this, "Failed to save data", Toast.LENGTH_SHORT).show(); // Even if save fails, you might still want to sign out? Or handle it differently // mAuth.signOut(); // finish(); } }); } else { String erro = ""; try { throw task.getException(); } catch (FirebaseAuthWeakPasswordException e) { erro = "Digite uma senha mais forte"; } catch (FirebaseAuthInvalidCredentialsException e) { erro = "Email invalido"; } catch (FirebaseAuthUserCollisionException e) { erro = "Email Registado"; } catch (Exception e) { erro = "Erro generico"; e.printStackTrace(); } Toast.makeText(SignUpUserActivity.this, erro, Toast.LENGTH_SHORT).show(); } } }); }
为什么这样能行?
By attaching addOnSuccessListener and addOnFailureListener to the save() task, we're telling the app:
- First, start the Firestore save operation
- Only when the save succeeds (or fails) should we run the code inside those listeners
- That's the perfect time to call
mAuth.signOut()andfinish()—since we know the data has either been saved or we've logged the failure.
This way, you get the behavior you want: create the user, save their data to Firestore, then sign out and close the activity.
内容的提问来源于stack exchange,提问作者Ricardo Rodrigues

