【问题标题】:Cloud Function stuck in an infinite loop云函数陷入无限循环
【发布时间】:2017-12-05 12:25:29
【问题描述】:
exports.addNewValue = functions.database.ref('/path')
.onWrite(event => {    
    event.data.adminRef.update({"timeSnapshot":Date.now()})})

看来 Date.now() 会导致函数中的无限循环,因为以下不会:

exports.addNewValue = functions.database.ref('/path')
.onWrite(event => {    
    event.data.adminRef.update({"timeSnapshot":"newString"})})

我该如何解决这个问题?

【问题讨论】:

  • onWrite() 仅在写入的值是更改时触发。写入Date.now() 会产生变化,而固定值newString 不会(在第一次之后)。你对这个功能的目标是什么?修改您正在收听的位置的值需要注意避免这种类型的循环。

标签: javascript firebase firebase-realtime-database infinite-loop google-cloud-functions


【解决方案1】:

如果您写回数据库中先前更改的相同位置,您可以预期以下事件序列:

  1. 功能由客户端的第一次更改触发
  2. 函数写回数据库
  3. 由于步骤 #2 中的写入,函数被第二次触发

所有与过滤器路径匹配的数据库写入,即使是来自同一函数的写入,都会触发该函数。

在第 3 步中,您需要一种策略来确定第二次函数调用是否应该导致再次写回数据库。如果不需要再次写入,则该函数应提前返回,以免触发另一次写入。通常,您会查看传递给函数的事件中的数据,并确定它是否已在第一次被修改。这可能涉及查看是否在数据库中设置了某些标志,或者您修改的数据是否需要更多更改。

Firebase 团队提供的许多code samples 都是这样做的。特别是看text moderation。此外,还有一个video that describes the problem 和一个可能的解决方案。最后,您有责任提出满足您需求的策略。

【讨论】:

    【解决方案2】:

    我认为以下应该可以正常工作:-

    exports.addNewValue = functions.database.ref('/path/timeSnapshot')
        .onWrite(event => {  event.data.adminRef.set(Date.now()) })
    

    上述背后的逻辑是,当您将触发函数放在更高节点上时(例如您的情况下为/path),每次对其任何子节点进行更改时都会触发该函数( /timestamp 在你的情况下) - 因此,无限循环。

    因此,作为一般做法,为了提高效率和成本效益,请确保您的触发函数具有尽可能低的路径节点。扁平化您的数据也确实有帮助。

    【讨论】:

      【解决方案3】:

      如果您到达这里时遇到查询问题,请尝试使用 .once('value') ...这意味着您只查看参考点一次...即

      ref.orderByChild("isLive").equalTo(true).once("value" , function(snapshot) {
      

      而不是

      ref.orderByChild("isLive").equalTo(true).on("value", function(snapshot) {
      

      因为第二个会让你一直在监听,当 ref 的数据发生变化时,监听器将接收到变化并再次运行你的代码块内的代码

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-17
        • 2019-03-03
        • 2020-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多