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

Flutter中使用Firestore向两个集合新增数据时连续点击计数异常怎么解决

问题根源
  • 你当前遇到的数值错误是典型的读-改-写并发冲突:快速点击时多个更新请求会读取到相同的旧统计值,各自累加后写入,最终结果会远小于实际点击次数
  • 额外加的Timer不仅没解决根本问题,反而会引发时序错乱,同时降低用户体验
修复方案

1. 替换自定义累加逻辑为Firestore原子增量操作

Firebase提供了FieldValue.increment()原子操作,累加逻辑在服务端执行,天然支持并发场景,不需要你提前读取旧值计算,不会出现冲突。

2. 移除所有Timer延迟逻辑

不需要用延迟控制请求频率,加按钮点击状态控制即可,点击后临时禁用按钮,直到异步操作完成再恢复,避免重复触发。

3. 可选:用事务保证数据一致性

如果需要确保cart子集合和users主集合的更新同时成功/失败,可以把两个操作包裹在Firestore事务中,避免出现数据不一致。

修改后的参考代码
// 记得导入cloud_firestore
import 'package:cloud_firestore/cloud_firestore.dart';

// StatefulWidget中定义状态变量控制按钮是否可点击
bool _isAdding = false;

!snapshot1.hasData || snapshot1.data!.docs.isEmpty
? InkWell(
    onTap: _isAdding ? null : () async {
      _isAdding = true; // 点击后立即禁用按钮
      final productDocId = snapshot.data!.docs[index].get('docId');
      final productPrice = snapshot.data!.docs[index].get('productPrice');
      final uid = snapshot3.data!.docs[0].get('uid');
      try {
        await cartupdate.doc(productDocId).set({
          'docId': productDocId,
          'productAmount': 1,
          'userId': "WEhxbwBPeI1HIZvIStkM",
          'cartTime': DateTime.now(),
        });
        print("product cart added and useramount + 1");
        // 用原子增量操作,不需要读旧值计算
        await users.doc(uid).update({
          'usercartAmount': FieldValue.increment(1),
          'usercheckoutAmount': FieldValue.increment(productPrice)
        });
      } catch (error) {
        print("Failed to add service: $error");
      } finally {
        _isAdding = false; // 操作完成恢复按钮可点击状态
      }
    },
    child: Container(
      child: Center(
        child: Icon(
          Icons.add,
          size: 35,
          // 不可点击时置灰图标,给用户明确反馈
          color: _isAdding ? Colors.grey : null,
        ),
      )
    )
)
: InkWell(
    onTap: _isAdding ? null : () async {
      _isAdding = true;
      final productDocId = snapshot.data!.docs[index].get('docId');
      final productPrice = snapshot.data!.docs[index].get('productPrice');
      final uid = snapshot3.data!.docs[0].get('uid');
      try {
        // 购物车已有商品,直接原子累加购买数量
        await cartupdate.doc(productDocId).update({
          'productAmount': FieldValue.increment(1),
        });
        print("product amount +1");
        await users.doc(uid).update({
          'usercartAmount': FieldValue.increment(1),
          'usercheckoutAmount': FieldValue.increment(productPrice)
        });
      } catch (error) {
        print("Failed to add service: $error");
      } finally {
        _isAdding = false;
      }
    },
    child: Container(
      child: Center(
        child: Icon(
          Icons.add,
          size: 35,
          color: _isAdding ? Colors.grey : null,
        ),
      )
    )
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:24:04