安卓接入Firestore后多账号提交数据覆盖旧数据,如何为每个用户创建独立文档?
问题根因
你当前代码固定指定了Users集合下的文档ID为User Information,Firestore的set()方法在目标文档ID已存在时,会直接覆盖该文档的全部内容,这就是切换账号提交后旧账号数据被覆盖的核心原因。
解决方案
根据你的业务需求可以选以下两种实现:
方案1:每个用户仅保留一份专属信息(同用户多次提交覆盖自己的信息,不会影响其他用户)
这是用户信息存储的常用方案,使用当前登录谷歌账号的唯一UID作为文档ID,不同用户的文档ID天然不重复:
- 首先确认已经接入Firebase Auth(已实现谷歌登录的场景默认已接入),在Activity中初始化FirebaseAuth实例
- 提交逻辑修改后的完整代码如下:
package com.example.attenda_attempt3; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import com.google.firebase.firestore.FirebaseFirestore; import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; public class StudentInformationFormActivity extends AppCompatActivity { Button btnNextStep; EditText etFirstName; EditText etLastName; EditText etSchoolID; FirebaseFirestore db = FirebaseFirestore.getInstance(); // 新增FirebaseAuth实例 FirebaseAuth mAuth = FirebaseAuth.getInstance(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_student_information_form); btnNextStep = findViewById(R.id.btnNextStep); etFirstName = findViewById(R.id.etFirstName); etLastName = findViewById(R.id.etLastName); etSchoolID = findViewById(R.id.etSchoolID); btnNextStep.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String firstName = etFirstName.getText().toString(); String lastName = etLastName.getText().toString(); String schoolID = etSchoolID.getText().toString(); // 获取当前登录用户 FirebaseUser currentUser = mAuth.getCurrentUser(); if (currentUser == null) { Toast.makeText(getApplicationContext(), "请先完成登录", Toast.LENGTH_SHORT).show(); return; } Map<String, Object> data = new HashMap<>(); data.put("First Name", firstName); data.put("Last Name", lastName); data.put("School ID", schoolID); data.put("User UID", currentUser.getUid()); // 可选,把UID也存入文档方便后续查询 // 用用户UID作为文档ID db.collection("Users").document(currentUser.getUid()).set(data) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void unused) { Toast.makeText(getApplicationContext(), "Saved", Toast.LENGTH_SHORT).show(); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull @NotNull Exception e) { Toast.makeText(getApplicationContext(), "Error Occurred, Data Not Saved", Toast.LENGTH_SHORT).show(); } }); } }); } }
方案2:每次点击提交都生成全新独立文档(同一用户多次提交也会生成多条互不影响的记录)
无需改动其他逻辑,只需把原有提交代码里的固定文档ID写法替换为add()方法,Firestore会自动生成全局唯一的随机文档ID,不会出现覆盖问题:
// 把原来的db.collection("Users").document("User Information").set(data)替换为下面的代码 db.collection("Users").add(data) .addOnSuccessListener(new OnSuccessListener<DocumentReference>() { @Override public void onSuccess(DocumentReference documentReference) { Toast.makeText(getApplicationContext(), "Saved,文档ID:" + documentReference.getId(), Toast.LENGTH_SHORT).show(); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull @NotNull Exception e) { Toast.makeText(getApplicationContext(), "Error Occurred, Data Not Saved", Toast.LENGTH_SHORT).show(); } });
注意事项
如果选择方案1,需要确保在进入该页面前用户已经完成谷歌账号登录,避免currentUser为空导致提交失败。
内容的提问来源于stack exchange,提问作者Abrahim Mahmud
相关产品推荐
相关产品推荐

