嗨我正在开发一个通知系统,但是我在删除已处理的通知数据时遇到问题.两次触发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}’中读取数据库的值 – 在传递给函数的情况下,它已经被传递给您.一定要read the docs about database triggers.你可以通过检查事件数据来知道函数是否第二次触发,如果它是null则可以提前返回,这意味着它被删除了.
此外,如果您正在处理单个承诺,则不需要Promise.all().只需在单个promise上使用then()继续处理,或从then()返回单个promise.
您可能希望查看一些显示数据库触发器的sample code.