【问题标题】:How can I ensure a value is only incremented once in Firestore?如何确保一个值在 Firestore 中只增加一次?
【发布时间】:2022-01-16 17:32:09
【问题描述】:

考虑以下最小示例:

const admin = require("firebase-admin")
admin.initializeApp({credential: "your creds here"})

const db = admin.firestore()

const fooRef: firebase.firestore.CollectionReference<firebase.firestore.DocumentData> =
  db.collection("foo")

setInterval(() => {
  fooRef
    .doc("bar")
    .update({
      anImportantCounter: admin.firestore.FieldValue.increment(1),
    })
}, 5000)

如果我运行此代码的 2 个实例(例如在滚动更新期间),是否可以确保字段 anImportantConuter 中的值不会每 5 秒增加两次?举个例子,假设时间间隔恰好是同步的。

firebase documentation page on distributed counters 的顶部附近,上面写着

在 Cloud Firestore 中,您大约每秒只能更新一个文档...

但我不确定这是否意味着重复写入被放入队列中以进行更新,或者它们根本不会发生。如果有解决这类事情的模式,那将是理想的。

感谢您的帮助。

【问题讨论】:

    标签: typescript google-cloud-firestore


    【解决方案1】:

    Firestore 仅允许每秒更新一个文档的限制是软限制,如 here 所述。该文档指出,Cloud Firestore 不会阻止您超过软限制的阈值,但这样做会影响性能。所以这个限制不是硬限制,你可以在短时间内超过限制。在您的情况下,相同代码的两个实例都可以执行(例如,在滚动更新期间),因为限制是软限制。但是将写入速率维持在每秒一次以上会增加延迟并导致争用错误。

    现在,如果您希望文档在 5 秒内更新一次,无论创建多少请求,您都需要在代码中设置某种条件,以便只处理一个请求。您还应该研究提到的分布式计数器解决方案here,它通过跨多个文档分片数据来解决每个文档的写入限制。

    现在为避免任何冲突,您应该考虑使用transactions。在并发编辑的情况下,Firestore 会再次运行整个事务。为避免重复更新,您可以将上次更新或请求提交时间戳存储在 Firestore 中,如 this example 中所述,以便新请求可以比较或引用以确保不执行重复更新。

    【讨论】:

      猜你喜欢
      • 2021-11-23
      • 1970-01-01
      • 2010-09-26
      • 2020-07-11
      • 2019-10-02
      • 1970-01-01
      • 2010-11-01
      • 2011-01-02
      • 2019-05-11
      相关资源
      最近更新 更多