【问题标题】:Scheduled Firebase/Cloud Functions Overlapping Problem计划的 Firebase/云功能重叠问题
【发布时间】:2026-01-10 15:10:01
【问题描述】:

我有一个每三分钟运行一次的预定函数。

它应该查看数据库(firestore),查询相关用户,向他们发送电子邮件或执行其他数据库操作。

一旦向用户发送电子邮件,它会使用字段“sent_to_today:true”更新用户。

如果 sent_to_today == true,该函数将在大约 24 小时内不会接触该用户,这是预期的。

但是,因为我有很多用户,并且该函数正在做很多工作,所以当它使用 sent_to_today:true 更新用户时,另一个调用会预先到达该用户并处理他们以发送电子邮件。

这会导致一些用户两次收到相同的电子邮件。

我有哪些选择来确保不会发生这种情况?

数据模型(简化):

users (Collection)
--- userId (document)
   --- sent_to_today  [Boolean]
   --- NextUpdateTime [String representing a Timestamp in ISO String]

函数运行时,if ("Now" >= NextUpdateTime) && (sent_to_today==false) 处理用户,否则跳过。

如何确保用户每天只被一次调用处理,而不是多次?

正如我所说,当它们被一个函数调用处理时(将“sent_to_today”设置为 true),下一次调用会到达该用户并处理它们。

任何有助于更好地构建数据或使用任何其他逻辑方法的帮助将不胜感激。

这是我正在考虑的一个想法:

  • 每次调用都会在开始时设置一个全局文档字段,“ex:busy_right_now:true”,完成后再次将其设置为false。如果后续调用在当前调用完成之前运行,如果 busy_right_now 仍然是 true,则它什么也不做。

【问题讨论】:

    标签: firebase google-cloud-firestore google-cloud-functions google-cloud-pubsub google-cloud-scheduler


    【解决方案1】:

    选项 1。

    你认为你的函数可以在十分钟内调用一次,而不是每三分钟一次吗?如果是 - 只需修改调度程序,并确保“最大实例”属性为“1”。由于函数超时时间仅为 540 秒,因此 10 分钟(600 秒)足以避免重叠。

    选项 2。

    When a firestore document is chosen for processing, the cloud function modifies some attribute - i.e. __state - and sets its value to IN_PROGRESS for example.处理完成后(发送电子邮件),该属性值将再次修改 - 例如为DONE。因此,如果函数选择了一个文档,该文档在 __state 属性中具有值 IN_PROGRESS - 它会简单地忽略并继续下一个。

    缺点-如果函数崩溃-可能有IN_PROGRESS状态的文档,应该有一些机制来监控和解决这种情况。

    选项 3。

    一个云函数通过 firestore 集合运行,并且对于要处理的每个文档 - 发送一个 pubsub 消息,该消息触发另一个云函数。该文件仅适用于一个 Firestore 文档。然而,需要“状态机”控制(如上面的选项 2)。选项 3 的好处 - 功能之间的专业化程度更高,并且可能有许多“第二”云功能并行运行。

    【讨论】: