Firebase Firestore中FieldValue.increment(1)自增逻辑未生效问题
问题根因
你使用的set()方法默认执行全量文档覆盖逻辑:如果目标文档已存在,会直接用你传入的字段集合替换文档内所有原有字段;如果文档不存在则新建文档。
你没有给set()开启合并写入配置,此时传入的FieldValue.increment(1)不会按增量规则和原有字段值做运算,最终写入的就是固定值1,这就是你测试时无论初始值设为多少,触发函数后usage都直接变成1的原因。
另外你代码里把set()的返回值赋值给documentSnapshot是无效写法,set()是无返回值的写入操作,不会返回文档快照。
修复方案
二选一即可:
- 方案1:保留
set()方法,开启合并写入模式,仅更新传入的字段,不覆盖文档内其他已有内容。只需要给set()传入SetOptions(merge: true)参数即可,这种写法兼容「文档不存在时自动创建、文档存在时增量更新」的场景,最适配你的需求:
addActivity( int day, ) async { await FirebaseFirestore.instance .collection('users') .doc(FirebaseAuth.instance.currentUser!.uid.toString()) .collection('activity') .doc('${globals.year}') .collection('week${globals.week}') .doc(day.toString()) .set( {'usage': FieldValue.increment(1)}, SetOptions(merge: true), // 开启字段合并,不覆盖全文档 ); }
- 方案2:使用
update()方法替代set()。update()本身就是局部字段更新方法,原生支持FieldValue.increment()原子增量操作。注意这个方法的限制是:如果目标文档不存在会直接抛出异常,不适合需要自动建文档的场景。写法参考:
addActivity( int day, ) async { await FirebaseFirestore.instance .collection('users') .doc(FirebaseAuth.instance.currentUser!.uid.toString()) .collection('activity') .doc('${globals.year}') .collection('week${globals.week}') .doc(day.toString()) .update({'usage': FieldValue.increment(1)}); }
测试提示
修改代码后建议先删除之前测试生成的异常文档,重新创建带初始usage值的文档再触发验证:初始值为2时触发1次函数,值应变为3,连续触发会持续累加。FieldValue.increment()是Firestore服务端执行的原子操作,高并发场景下也不会出现计数偏差,完全适配后续图表展示的统计需求。
内容的提问来源于stack exchange,提问作者Jonas Jacob Biermann
相关产品推荐
相关产品推荐

