为什么我的firebase回调被多次触发?

时间:2015-01-26 23:33:59

标签: node.js email firebase

我有一个小型节点服务器在某些情况下监听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); });
            }
        });
    }                                                                                                                                                    
});

但是,我一直收到重复的电子邮件。最奇怪的是,尽管发送了多封电子邮件,但每个申请人只会显示一份“新申请人:......”声明。

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

谢谢!

2 个答案:

答案 0 :(得分:2)

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

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);
            });
    }
});

答案 1 :(得分:1)

每次authWithCustomToken()成功时,都会触发您的child_added事件。每次重新加载或重新验证页面时,都会附加新的侦听器,每个用户都会触发一个新的child_added事件,并且将重新发送电子邮件。

  

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

(强调我的)

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

然后,您的服务可以读取队列并在成功完成后删除任务。通过这种方式,您将不会有重复。

相关问题