【问题标题】:Optimal Firebase Cloud Function to be called everytime a child is added每次添加孩子时调用的最佳 Firebase 云函数
【发布时间】:2020-11-07 22:42:08
【问题描述】:

我希望每次将新用户添加到匹配对象时执行一个函数,以增加匹配用户的数量。

exports.onCreateMatchmakingUser = functions.database.ref('/matchmaking/{$uid}').onCreate((snapshot, context) => {
    const currentMatchmakingAmount = snapshot.ref.parent.child('matchmakingAmount').val();
    return snapshot.ref.parent.update({matchmakingAmount: currentMatchmakingAmount+1});
});

我不想获取整个 matchmaking 对象然后获取数字,我只想要 matchmakingAmount。 snapshot.ref.parent 是否会造成问题(它是获取整个匹配对象,还是仅获取它的引用而不下载其数据)?如果是这样,我该如何解决这个问题并编写另一个函数来更新数字而无需不必要的下载?

【问题讨论】:

    标签: node.js firebase-realtime-database google-cloud-functions


    【解决方案1】:

    代码中的snapshot.ref.parent.child('matchmakingAmount') 不会从数据库中读取任何内容。相反,它只是在数据库中设置了对matchmakingAmount 的引用。您仍然需要使用once("value") 明确阅读它:

    let amountRef = snapshot.ref.parent.child('matchmakingAmount');
    return amountRef.once("value").then((amount) => {
      let currentMatchmakingAmount = amount.val();
      return amountRef.set(currentMatchmakingAmount+1});
    });
    

    幸运的是,现在有一种更简单的方法可以做到这一点,因为 Firebase 有一个内置的 increment 运算符。有了这个,以上归结为:

    let amountRef = snapshot.ref.parent.child('matchmakingAmount');
    amountRef.set(admin.database.ServerValue.increment(1));
    

    此方法还解决了您的方法中存在的竞争条件:如果两个人几乎同时触发 Cloud Function,则两个写入可能会相互影响。通过使用不会发生的服务器端increment

    另见:

    【讨论】:

    • 在实现你写的第二段代码时,我是否也应该返回amountRef.set(admin.database.ServerValue.increment(1));因为 set 返回一个承诺?
    • 是的。由于写入是异步的,因此您希望 Cloud Function 在完成之前一直保持活动状态,为此您需要将承诺返回给容器。
    猜你喜欢
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 2020-09-24
    • 2018-10-02
    • 1970-01-01
    • 2019-01-18
    相关资源
    最近更新 更多