为什么我的firebasecallback被多次触发?

我有一个小型节点服务器,监听Firebase的变化,并在特定条件下发送电子邮件。 代码如下:

var Firebase = require('firebase'); var ref = new Firebase(process.env.FIREBASE_URL); ref.authWithCustomToken(process.env.FIREBASE_SECRET, function (err) { if (err) { console.log(new Date().toString(), 'Firebase Authentication Failed!', err); EmailService.send('Firebase authentication failed', 'errors@domain.com', err); } else { ref.child('applicants').on('child_added', function (snapshot) { var applicant = snapshot.val(); if (!(applicant.alerts && applicant.alerts.apply)) { console.log(new Date().toString(), 'New Applicant: ', applicant); var body = applicant.firstName + ' ' + applicant.lastName + '\n' + applicant.email + '\n' + applicant.phoneNumber; EmailService .send('New Applicant', 'applicants@entercastle.com', body) .then(function () { ref.child('applicants').child(snapshot.key()).child('alerts').child('apply').set(true); }) .catch(function (err) { console.log(new Date().toString(), err); }); } }); } }); 

但是,我不断收到重复的电子邮件。 最奇怪的是,尽pipe发送了多封电子邮件,但日志只显示每个申请人的单个“新申请人:…”声明。

任何想法是什么导致这个或如何解决它?

谢谢!

每次authWithCustomToken()成功时,您的child_added事件都会被触发。 每次页面重新加载或重新authentication时,新的监听器都会被附加,每个用户都会触发一个新的child_added事件,邮件将被重新发送。

在检索Firebase中的项目列表时,通常会使用child_added事件。 与返回位置的全部内容的值不同, 为每个现有的子项触发一次 child_added,然后在每次将新的子项添加到指定的path时再触发一次 。 事件callback传递一个包含新的孩子数据的快照。

(重点是我的)

如果您只想发送一次邮件,则更好的方法是使用队列策略 ,在创build用户时“排队”一个活动(例如欢迎电子邮件)。

然后,您的服务可以读取队列并在成功完成后删除该任务。 这样,你就不会有蠢货了。

在添加新侦听器之前删除现有侦听器将解决此问题

on()事件之前试试这个off() on()事件

 ref.child('applicants').off(); // it will remove existing listener 

那么你的代码

 ref.child('applicants').on('child_added', function(snapshot) { var applicant = snapshot.val(); if (!(applicant.alerts && applicant.alerts.apply)) { console.log(new Date().toString(), 'New Applicant: ', applicant); var body = applicant.firstName + ' ' + applicant.lastName + '\n' + applicant.email + '\n' + applicant.phoneNumber; EmailService .send('New Applicant', 'applicants@entercastle.com', body) .then(function() { ref.child('applicants').child(snapshot.key()).child('alerts').child('apply').set(true); }) .catch(function(err) { console.log(new Date().toString(), err); }); } });