Firebase:如何在单次操作中更新同一文档并获取其最新计数值?
实现优化
- 你当前的两次请求写法,核心原因是
increment是服务端计算的原子增量,客户端在发起更新请求时,根本无法预知服务端算出的最终累加结果,才需要在更新完成后额外发起一次查询。 - 可以借助Firestore原生的事务能力简化流程,完全省去二次查询的步骤。事务的执行逻辑为:先对计数器文档做原子读操作,拿到当前存储的累计值后,直接在事务内计算出累加1的新序号,再写回文档,整个读写流程在服务端事务内闭环,客户端仅需一次交互请求,就能直接拿到可用的收据序号。
- 这种方案相比现有实现还有额外的可靠性提升:能够避免高并发场景下生成重复序号的问题。你当前的
update+get写法在并发环境下,哪怕更新成功,后续get拿到的数值也可能被其他并发请求抢先修改,最终出现收据序号错乱。
对应的优化代码:
const receiptCounterRef = admin.firestore().collection("totalTransactions").doc("total"); admin.firestore().runTransaction(async (transaction) => { // 事务内原子读取当前计数器值,全程无并发冲突 const counterSnapshot = await transaction.get(receiptCounterRef); const currentTotal = counterSnapshot.data().total || 0; const newReceiptNo = currentTotal + 1; // 直接写回累加后的新值,无需写完再拉取 transaction.update(receiptCounterRef, { total: newReceiptNo }); // 将计算好的序号返回给后续业务流程 return newReceiptNo; }).then((receiptNo) => { // 此处可直接使用生成的连续收据序号,无额外二次请求 console.log("当前生成的收据序号:", receiptNo); });
内容的提问来源于stack exchange,提问作者Chinmay Atrawalkar
相关产品推荐
相关产品推荐

