You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase Database写入异常:谷歌账号切换后数据写入问题

Fixing Firebase Database Write Issues with Google Auth Switching

Hey there, let's break down and fix your two main issues: needing two logouts to trigger a database write, and overwriting entries instead of adding new ones when switching Google accounts.

1. Why You Need Two Logouts to Write Data

This usually happens because your login state listener isn't properly detecting the first login state change or your data-writing logic isn't triggered at the right moment. Common culprits:

  • You're only triggering the write after a logout → login cycle (instead of on every successful login)
  • Your AuthStateListener isn't registered early enough (e.g., not in onCreate()) or isn't handling initial login state correctly
  • Leftover cached user state is causing the first login to skip the write logic

Fix for the Double-Logout Issue

Use Firebase Auth's AuthStateListener to detect any login state change, including the initial app launch if a user is already signed in. Here's how to implement it correctly in your MainActivity:

private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference mDatabase;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mAuth = FirebaseAuth.getInstance();
    mDatabase = FirebaseDatabase.getInstance().getReference();

    // Initialize the AuthStateListener to catch all login state changes
    mAuthListener = firebaseAuth -> {
        FirebaseUser user = firebaseAuth.getCurrentUser();
        if (user != null) {
            // Trigger data write immediately when user signs in
            writeUserToDatabase(user);
        } else {
            // Optional: Clear cached user data when signed out
        }
    };
}

@Override
protected void onStart() {
    super.onStart();
    // Register listener when activity starts to catch initial login state
    mAuth.addAuthStateListener(mAuthListener);
}

@Override
protected void onStop() {
    super.onStop();
    // Unregister listener to avoid memory leaks
    if (mAuthListener != null) {
        mAuth.removeAuthStateListener(mAuthListener);
    }
}

private void writeUserToDatabase(FirebaseUser user) {
    // Create a user object with Google account details
    User userInfo = new User(
        user.getDisplayName(),
        user.getEmail(),
        user.getPhotoUrl() != null ? user.getPhotoUrl().toString() : "",
        user.getUid(),
        System.currentTimeMillis() // Add timestamp to track login time
    );

    // This fixes the overwrite issue (more on that below)
    mDatabase.child("user_logins").push().setValue(userInfo)
        .addOnSuccessListener(aVoid -> Log.d("Firebase", "Login data written successfully"))
        .addOnFailureListener(e -> Log.e("Firebase", "Failed to write login data", e));
}

2. Why Entries Are Overwritten Instead of Added

The overwrite problem almost always comes from using a fixed key (like the user's UID) for each entry. For example, if you were doing:

mDatabase.child("users").child(user.getUid()).setValue(userInfo);

This will overwrite the same node every time that user logs in. To add a new entry every time a user logs in (including switching accounts), use Firebase's push() method—it generates a unique, timestamp-based key for each new entry.

Optional: Only Add Entries When Switching Accounts

If you want new entries only when switching to a different account (not every login of the same account), add a check using SharedPreferences to track the last logged-in UID:

private String lastLoggedInUid;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ... existing code ...
    SharedPreferences prefs = getSharedPreferences("AppPrefs", MODE_PRIVATE);
    lastLoggedInUid = prefs.getString("last_uid", null);
}

private void writeUserToDatabase(FirebaseUser user) {
    if (!user.getUid().equals(lastLoggedInUid)) {
        // Only write data if it's a new account
        User userInfo = new User(/* ... */);
        mDatabase.child("user_logins").push().setValue(userInfo);
        
        // Update the last logged-in UID
        SharedPreferences.Editor editor = getSharedPreferences("AppPrefs", MODE_PRIVATE).edit();
        editor.putString("last_uid", user.getUid());
        editor.apply();
    }
}

Additional Checks for Proper Behavior

  • Ensure your logout flow fully signs out both Google and Firebase Auth to avoid leftover state:
private void signOut() {
    // Sign out from Google
    GoogleSignIn.getClient(this, GoogleSignInOptions.DEFAULT_SIGN_IN).signOut();
    // Sign out from Firebase Auth
    mAuth.signOut();
    // Clear last logged-in UID
    SharedPreferences.Editor editor = getSharedPreferences("AppPrefs", MODE_PRIVATE).edit();
    editor.remove("last_uid");
    editor.apply();
}
  • Verify your Firebase Database rules allow write access (use allow write: if true; for testing, but tighten this for production).

内容的提问来源于stack exchange,提问作者Rogerto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:33:41