Firebase数据库onWrite的云功能触发两次 [英] Cloud Functions for Firebase database onWrite triggered twice

本文介绍了Firebase数据库onWrite的云功能触发两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我正在开发一个通知系统,但是在删除已处理的通知数据时遇到了麻烦. onWrite事件侦听器被触发两次,导致两个通知.

您能帮我找到解决方法,以便onWrite事件侦听器不应触发两次吗?删除已处理的数据很重要.

exports.sendMessageNotification = functions.database.ref('/notification/message/{recipientUid}/{senderUid}').onWrite(event => {
/* processing notification and sends FCM */

return admin.messaging().sendToDevice(tokens, payload).then(response => {
      // For each message check if there was an error.
      const toRemove = [];
      response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
          console.error('Failure sending notification to', tokens[index], error);
          // Cleanup the tokens who are not registered anymore.
          if (error.code === 'messaging/invalid-registration-token' ||
              error.code === 'messaging/registration-token-not-registered') {
            toRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
          }
        }
      });

      //Deletes processed notification
      console.log("Removing notification");
      const getNotificationPromise = admin.database().ref(`/notification/message/${recipientUid}/${senderUid}`).once('value');
      return Promise.all([getNotificationPromise]).then(results => {
        const notificationSnapshot = results[0];
        toRemove.push(notificationSnapshot.ref.remove());

        console.log("Removing tokens.")
        return Promise.all(toRemove);
      });
      //return Promise.all(tokensToRemove);
    });
});

})

解决方案

这是一个常见错误.您正在写回该函数首次触发时匹配的相同数据库位置(通过删除数据).这意味着删除将再次触发该函数以处理第二个更改.这是目前的预期行为.

您将需要想出一种方法来检测第二次写入是由于数据删除而发生的.另外,您当前在功能上做的太多.无需在'/notification/message/{recipientUid}/{senderUid}'处读取数据库的值-在传递给函数的事件中,该值已经传递给您.请确保阅读有关数据库触发器的文档.您可以通过检查事件数据并提前返回是否为null来知道该函数是否是第二次触发的,这意味着该函数已被删除.

此外,如果您要处理一个承诺,则不需要Promise.all().只需在单个承诺中使用then()即可继续处理,或者从then()返回该单个承诺.

您可能想看一些显示数据库触发器的示例代码. /p>

Hi I am developing a notification system, but I am having trouble deleting the processed notification data. The onWrite event listener is triggered twice resulting to two notifications.

Can you help me find a work around so that onWrite event listener should not be triggered twice? It is important to delete the processed data.

exports.sendMessageNotification = functions.database.ref('/notification/message/{recipientUid}/{senderUid}').onWrite(event => {
/* processing notification and sends FCM */

return admin.messaging().sendToDevice(tokens, payload).then(response => {
      // For each message check if there was an error.
      const toRemove = [];
      response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
          console.error('Failure sending notification to', tokens[index], error);
          // Cleanup the tokens who are not registered anymore.
          if (error.code === 'messaging/invalid-registration-token' ||
              error.code === 'messaging/registration-token-not-registered') {
            toRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
          }
        }
      });

      //Deletes processed notification
      console.log("Removing notification");
      const getNotificationPromise = admin.database().ref(`/notification/message/${recipientUid}/${senderUid}`).once('value');
      return Promise.all([getNotificationPromise]).then(results => {
        const notificationSnapshot = results[0];
        toRemove.push(notificationSnapshot.ref.remove());

        console.log("Removing tokens.")
        return Promise.all(toRemove);
      });
      //return Promise.all(tokensToRemove);
    });
});

})

解决方案

This is a common mistake. You are writing back into the same database location (by removing the data) that was matched when the function first triggered. This means that removal will be triggering the function again to handle that second change. This is currently the expected behavior.

You will need to come up with a way to detect that the second write happened in response to the removal of data. Also, you are currently doing too much work in your function. There's no need to read the value of the database at '/notification/message/{recipientUid}/{senderUid}' - it is already being delivered to you in the event that's passed to the function. Be sure to read the docs about database triggers. You can know if the function was triggered a second time by examining the event data and returning early if it's null, which means it was removed.

Also, you don't need Promise.all() if you are dealing with a single promise. Just use then() on that single promise to continue processing, or return that single promise from then().

You might want to look at some of the sample code that shows database triggers.

这篇关于Firebase数据库onWrite的云功能触发两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆