Firebase Google登录后登出再登录,用户节点下其他数据被删除
解决Firebase Google登录后实时数据库数据被覆盖的问题
我懂你遇到的麻烦了!用同一Google账号登出再登录时,用户ID下的其他数据被清空,根源在于你用的更新方法是覆盖整个节点,而不是仅更新用户名和邮箱这两个字段。
问题原因
Firebase实时数据库里的setValue()(你提到的put应该对应这个方法)会直接替换目标节点的所有内容——也就是说,当你再次登录时,它会把用户ID节点下原有的所有数据都删掉,再写入新的用户名和邮箱,自然其他节点就没了。
解决方案:用updateChildren()替代覆盖操作
我们可以用updateChildren()方法,它只会更新你指定的字段,保留节点里原有的其他数据。给你修改后的代码示例:
private void firebaseAuthWithGoogle(GoogleSignInAccount account) { AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null); mAuth.signInWithCredential(credential) .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { // 获取当前登录用户 FirebaseUser user = mAuth.getCurrentUser(); if (user != null) { DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("users").child(user.getUid()); // 构建要更新的字段集合 Map<String, Object> userUpdates = new HashMap<>(); userUpdates.put("username", account.getDisplayName()); userUpdates.put("email", account.getEmail()); // 仅更新指定字段,不影响其他现有数据 userRef.updateChildren(userUpdates) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void unused) { Log.d(TAG, "用户基本信息更新成功"); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Log.w(TAG, "用户信息更新失败", e); } }); } } else { Log.w(TAG, "signInWithCredential:failure", task.getException()); } } }); }
进阶优化:区分首次登录与重复登录
如果想在用户首次登录时完整创建用户节点,后续登录仅更新用户名/邮箱,可以先检查节点是否存在:
private void firebaseAuthWithGoogle(GoogleSignInAccount account) { AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null); mAuth.signInWithCredential(credential) .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { FirebaseUser user = mAuth.getCurrentUser(); if (user != null) { DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("users").child(user.getUid()); // 单次查询节点是否存在 userRef.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (!snapshot.exists()) { // 首次登录:创建完整用户节点 User userData = new User(account.getDisplayName(), account.getEmail()); userRef.setValue(userData); } else { // 重复登录:仅更新指定字段 Map<String, Object> userUpdates = new HashMap<>(); userUpdates.put("username", account.getDisplayName()); userUpdates.put("email", account.getEmail()); userRef.updateChildren(userUpdates); } } @Override public void onCancelled(@NonNull DatabaseError error) { Log.w(TAG, "检查用户节点失败", error.toException()); } }); } } else { Log.w(TAG, "signInWithCredential:failure", task.getException()); } } }); }
这样处理后,不管用户重复登录多少次,原来存在的其他数据都不会被删除啦!
内容的提问来源于stack exchange,提问作者user8554744
相关产品推荐
相关产品推荐

