【问题标题】:Cloud Functions for Firebase OnWriteFirebase OnWrite 的云函数
【发布时间】:2017-08-02 06:53:29
【问题描述】:

我正在查看 Firebase 的新云功能,它说在执行 OnWrite 时应注意不要将数据保存回同一个子级。 (这将再次触发触发器)。

所以我想弄清楚,如何在记录上设置修改日期?

【问题讨论】:

  • 您是否考虑过将修改日期设置为您从客户端编写的内容的一部分?使用ServerValue.TIMESTAMP?
  • 这真的只是一个例子......我不想要关于如何设置修改日期的解决方案。我想要一个关于如何更改数据服务器端的解决方案。
  • 可以说,客户更改数据,我需要处理金融交易,然后删除记录。删除是对 OnWrite 的更改,所以我不确定如何组织该代码。
  • 不用担心。但是,我建议您编辑问题以使用您最后的评论作为示例,因为我认为这是一个更有可能的用例。

标签: firebase firebase-realtime-database google-cloud-functions


【解决方案1】:

问题不在于您不能或不应该更改数据,而在于您需要防范无限循环。例如,设置时间戳可以重新触发设置时间戳的函数,该函数将重新触发......等等。

然而,您可以做的是通过确保以幂等方式标记状态来保护您的代码,这样相同的代码就不会重新触发。例如:

exports.doThing = functions.database.ref('/events/{id}').onWrite(ev => {
  // prevent loops by guarding on data state
  if (ev.data.child('didThingAt').exists()) return;

  // do thing here...

  return ev.data.adminRef.update({
    didThingAt: admin.database.ServerValue.TIMESTAMP
  });
});

【讨论】:

  • 有帮助的干杯
  • 对不起,有人能解释一下这是做什么的吗?我通常知道为什么我们需要做这样的事情,但这段代码对我来说并不完全清楚。我的技能很差
  • 这是用键didThingAt 向位置写入一个新值。当函数触发时,它会检查didThingAt 字段是否已经存在,如果存在则简单停止执行。在这两个语句之间,您将执行“仅一次”逻辑。
  • 如果一个字段被多次更新/递增(例如,每次执行操作时递增一个计数器),有没有办法让函数只递增该字段一次,并认识到字段已更新且不再执行?我唯一能想到的是将函数 .onWrite 事件放在不同的表引用上。并调用另一个函数来分别更新包含递增字段的表。
  • 希望有一种方法可以在从云函数调用写入时抑制这种情况的触发。
【解决方案2】:

我了解 firebase 函数提供了更好的方法:

方法是验证之前的事件是否存在。 如果是这样,什么都不做,然后返回,你的工作...... 此外,您可以验证项目是否正在被删除。

  if (event.data.previous.exists()) {
    return;
  }
  // Exit when the data is deleted.
  if (!event.data.exists()) {
    return;
  }

这是来自firebase documentation 的完整示例。

exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onWrite(event => {
      // Only edit data when it is first created.
      if (event.data.previous.exists()) {
        return;
      }
      // Exit when the data is deleted.
      if (!event.data.exists()) {
        return;
      }
// Grab the current value of what was written to the Realtime Database.
const original = event.data.val();
console.log('Uppercasing', event.params.pushId, original);
const uppercase = original.toUpperCase();
// You must return a Promise when performing asynchronous tasks inside a Functions such as
// writing to the Firebase Realtime Database.
// Setting an "uppercase" sibling in the Realtime Database returns a Promise.
return event.data.ref.parent.child('uppercase').set(uppercase);

【讨论】:

  • 这就是导致问题的例子。它没有解决问题,因为如果你写回记录,那么 event.data.previous.exists() 实际上从 write 函数的第一次解析就存在了。
猜你喜欢
  • 2019-01-31
  • 2018-03-28
  • 1970-01-01
  • 2018-05-04
  • 2019-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-20
相关资源
最近更新 更多