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

如何在Firestore中按日期跟踪并更新计步器项目的对应文档?

问题核心原因

  1. 遍历逻辑错误:你在遍历文档的循环中,只要遇到第一个非当日的文档,就会直接触发新建逻辑并终止遍历,完全不会检查剩余文档中是否存在当日对应的文档,导致每次都会重复新建。
  2. 日期格式化存在本地化风险:你使用的E, MMM dd yyyy格式包含星期、月份的本地化缩写,当用户系统语言和你生成日期时的语言不一致时,两个实际同一天的日期字符串会对比失败。
  3. 查询效率极低:每次点击都拉取整个步数集合的所有文档再遍历,数据量大之后会严重影响性能且浪费流量。

修复方案

1. 优先优化日期标识格式

把日期标识换成无本地化风险的纯数字格式,比如yyyyMMdd(示例:20240520),完全规避语言差异导致的对比失败问题。

2. 优化Firestore查询逻辑

直接查询匹配当日日期的文档,不需要拉取全量数据遍历:

修改后的参考代码

mSaveDataToFireStore.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        String stepCountNum = mTV_StepCounter.getText().toString();
        String stepCountMeter = mTV_StepCounter_meter.getText().toString();
        String stepCalories = mCalories_Burn.getText().toString();
        String stepDuration = mCounter_Duration.getText().toString();
        
        // 统一指定Locale.US避免本地化差异,也可以直接换成yyyyMMdd纯数字格式更稳妥
        DateFormat dateFormat = new SimpleDateFormat("E, MMM dd yyyy", Locale.US);
        Date date = new Date();
        String todayDateStr = dateFormat.format(date);
        
        Calendar callForDate = Calendar.getInstance();
        SimpleDateFormat currentDay = new SimpleDateFormat("E", Locale.US);
        String saveCurrentDay = currentDay.format(callForDate.getTime());
        SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm:ss a", Locale.US);
        String saveCurrentTime = currentTime.format(callForDate.getTime());

        FirebaseUser AppUser = FirebaseAuth.getInstance().getCurrentUser();
        if (AppUser == null) return;
        String userId = AppUser.getUid();
        CollectionReference colRef = FirebaseFirestore.getInstance()
                .collection("REGISTERED USERS").document(userId)
                .collection("STEP COUNTER");

        // 直接查询当日的文档,不用拉全量集合
        colRef.whereEqualTo("mStepDate", todayDateStr)
                .get()
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                        StepCounter_Model stepCountUpdate = new StepCounter_Model(todayDateStr, saveCurrentDay, saveCurrentTime, stepCountNum,
                                stepCountMeter, stepCalories, stepDuration);
                        if (!queryDocumentSnapshots.isEmpty()) {
                            // 存在当日文档,直接更新
                            DocumentSnapshot doc = queryDocumentSnapshots.getDocuments().get(0);
                            Map<String, Object> saveInfo = new HashMap<>();
                            saveInfo.put("mStepDate", stepCountUpdate.mStepDate);
                            saveInfo.put("mStepDay", stepCountUpdate.mStepDay);
                            saveInfo.put("mStepTime", stepCountUpdate.mStepTime);
                            saveInfo.put("mStepCount", stepCountUpdate.mStepCount);
                            saveInfo.put("mStepCountMeter", stepCountUpdate.mStepCountMeter);
                            saveInfo.put("mStepCalories", stepCountUpdate.mStepCalories);
                            saveInfo.put("mStepDuration", stepCountUpdate.mStepDuration);

                            colRef.document(doc.getId()).update(saveInfo);
                            Toast.makeText(StepTrackerActivity.this, "数据更新成功", Toast.LENGTH_SHORT).show();
                        } else {
                            // 不存在当日文档,新建
                            addTo_FireStoreDB(todayDateStr, saveCurrentDay, saveCurrentTime, stepCountNum,
                                    stepCountMeter, stepCalories, stepDuration);
                            Toast.makeText(StepTrackerActivity.this, "今日数据已保存", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }
});

额外优化建议

可以直接用日期字符串作为Firestore文档的ID,比如文档ID直接设为20240520这种格式,不需要查询,直接用set方法传入SetOptions.merge()就能自动实现存在则更新、不存在则新建的逻辑,代码更简洁效率也更高:

// 示例用yyyyMMdd当文档ID
SimpleDateFormat idFormat = new SimpleDateFormat("yyyyMMdd", Locale.US);
String docId = idFormat.format(new Date());
colRef.document(docId).set(stepCountUpdate, SetOptions.merge());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 09:15:00