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

Android端Firestore分类数据登出丢失问题求助

问题分析与解决方案

核心问题原因

  • 登出后重新登录时,未从Firestore重新加载当前用户的分类数据,导致界面为空
  • SharedPreferences仅实现了存储逻辑,但未在登录后执行读取操作,且它是本地存储,无法替代Firestore的云端持久化作用
  • 代码中TaskGroup的groupId硬编码为"groupId",无法与Firestore生成的文档ID对应,可能破坏数据关联逻辑
  • 添加分类时新建CategoriesAdapter实例,而非复用主活动中已绑定的适配器,可能导致界面更新失效

分步解决方案

1. 修复Firestore数据加载逻辑(关键)

在主活动的onStart方法中添加数据查询逻辑,确保登录后自动拉取当前用户的分类:

@Override
protected void onStart() {
    super.onStart();
    FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
    if (currentUser != null) {
        loadCategoriesFromFirestore(currentUser.getUid());
    }
}

private void loadCategoriesFromFirestore(String userId) {
    FirebaseFirestore firestore = FirebaseFirestore.getInstance();
    firestore.collection("categories")
            .whereEqualTo("userId", userId)
            .addSnapshotListener(new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
                    if (error != null) {
                        Toast.makeText(MainActivity.this, "加载分类失败: " + error.getMessage(), Toast.LENGTH_SHORT).show();
                        return;
                    }
                    categoriesList.clear();
                    for (QueryDocumentSnapshot doc : value) {
                        TaskGroup taskGroup = doc.toObject(TaskGroup.class);
                        taskGroup.setGroupId(doc.getId());
                        categoriesList.add(taskGroup);
                    }
                    if (categoriesAdapter != null) {
                        categoriesAdapter.notifyDataSetChanged();
                    }
                }
            });
}

2. 修正Firestore分类存储的groupId

添加分类到Firestore时,用生成的文档ID更新TaskGroup的groupId,确保数据关联正确:

firestore.collection("categories").add(newGroup)
        .addOnSuccessListener(documentReference -> {
            Toast.makeText(MainActivity.this, "Category saved in Firestore", Toast.LENGTH_SHORT).show();
            // 更新TaskGroup的groupId为Firestore文档ID
            newGroup.setGroupId(documentReference.getId());
            // 同步更新本地列表
            int index = categoriesList.indexOf(newGroup);
            if (index != -1) {
                categoriesList.set(index, newGroup);
                categoriesAdapter.notifyItemChanged(index);
            }
            saveCategoryToSharedPreferences(categoryName);
        })

3. 优化SharedPreferences读取逻辑(可选)

若需本地缓存,在主活动启动时读取SharedPreferences的分类并同步到界面(核心数据仍以Firestore为准):

private void loadCategoriesFromSharedPreferences() {
    SharedPreferences sharedPreferences = getSharedPreferences("categories", MODE_PRIVATE);
    Set<String> categoriesSet = sharedPreferences.getStringSet("categories", new HashSet<>());
    for (String name : categoriesSet) {
        boolean exists = false;
        for (TaskGroup group : categoriesList) {
            if (group.getCategoryName().equals(name)) {
                exists = true;
                break;
            }
        }
        if (!exists) {
            TaskGroup tempGroup = new TaskGroup(name, "", name, new ArrayList<>(), Collections.singletonList(R.drawable.ic_lists), 0, true, FirebaseAuth.getInstance().getCurrentUser().getUid(), true);
            categoriesList.add(tempGroup);
        }
    }
    if (categoriesAdapter != null) {
        categoriesAdapter.notifyDataSetChanged();
    }
}

4. 复用适配器实例

在主活动中全局声明适配器,避免重复创建:

// 主活动类成员变量
private CategoriesAdapter categoriesAdapter;

// 在onCreate中初始化
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    categoriesList = new ArrayList<>();
    categoriesAdapter = new CategoriesAdapter(categoriesList, this);
    // 绑定RecyclerView
    RecyclerView recyclerView = findViewById(R.id.categories_recycler);
    recyclerView.setAdapter(categoriesAdapter);
    // ...其他初始化逻辑
}

关键注意事项

  • 始终以Firestore云端数据为唯一可信源,SharedPreferences仅作为本地缓存辅助使用
  • 配置Firestore规则,确保用户仅能读写自己的分类数据:
    match /categories/{doc} { 
        allow read, write: if request.auth != null && request.auth.uid == resource.data.userId; 
    }
    
  • 登出时清空本地categoriesList和SharedPreferences数据,避免数据混淆

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 07:52:33