作者:炎木柏玮 | 来源:互联网 | 2023-02-08 00:22
嗨我正在开发一个通知系统,但是我在删除已处理的通知数据时遇到问题.该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);
});
});
})
Doug Stevens..
6
这是一个常见的错误.您正在写回到首次触发函数时匹配的相同数据库位置(通过删除数据).这意味着删除将再次触发该功能以处理第二次更改.这是目前的预期行为.
您需要想出一种方法来检测第二次写入是为了响应数据的删除.此外,您目前在功能方面做了太多工作.没有必要读取数据库的值'/notification/message/{recipientUid}/{senderUid}'
- 它已经在传递给函数的事件中传递给您.请务必阅读有关数据库触发器的文档.您可以通过检查事件数据来知道该函数是否第二次被触发,如果它为null则可以提前返回,这意味着它已被删除.
此外,如果您正在处理单个承诺,则不需要Promise.all().只需在单个promise上使用then()继续处理,或从then()返回单个promise.
您可能希望查看一些显示数据库触发器的示例代码.
1> Doug Stevens..:
这是一个常见的错误.您正在写回到首次触发函数时匹配的相同数据库位置(通过删除数据).这意味着删除将再次触发该功能以处理第二次更改.这是目前的预期行为.
您需要想出一种方法来检测第二次写入是为了响应数据的删除.此外,您目前在功能方面做了太多工作.没有必要读取数据库的值'/notification/message/{recipientUid}/{senderUid}'
- 它已经在传递给函数的事件中传递给您.请务必阅读有关数据库触发器的文档.您可以通过检查事件数据来知道该函数是否第二次被触发,如果它为null则可以提前返回,这意味着它已被删除.
此外,如果您正在处理单个承诺,则不需要Promise.all().只需在单个promise上使用then()继续处理,或从then()返回单个promise.
您可能希望查看一些显示数据库触发器的示例代码.
这个答案帮助我了解到我可以通过`const data = event.data;`来获取数据快照,并在函数内部添加一个if,如果没有值,则返回`if(data == undefined ||!data.val() ){return;}`