云功能陷入无限循环

时间:2017-07-01 20:30:18

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

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"})})

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:6)

如果您回写以前更改过的数据库中的相同位置,您可以预期这一系列事件:

  1. 通过客户端的第一次更改
  2. 触发功能
  3. 函数写回数据库
  4. 由于在步骤#2期间写入,第二次触发功能
  5. 对数据库的所有写入都与过滤器路径匹配,即使是来自同一函数的那些,也会触发该函数。

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

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

答案 1 :(得分:1)

我认为以下情况应该可行: -

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

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

因此,作为一般惯例,为了提高效率和成本效益,请确保您的触发器功能具有尽可能低的路径节点。平整数据确实也有助于此。

答案 2 :(得分:0)

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

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

而不是

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

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