2015-01-26 102 views
1

我有一个小型节点服务器,监听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', '[email protected]', 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', '[email protected]', 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

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

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

(重点煤矿)

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

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

+0

嗯,我还以为'如果(!(applicant.alerts && applicant.alerts.apply))'会为每个现有的孩子触发child_added触发一次。看起来好像auth回调被多次调用并导致监听器多次附加,所以我添加了一个名为firstLoad的布尔值,在注册监听器之前检查auth回调,但我仍然得到重复。我可能最终走上队列路线,但我仍然想知道我错过了什么。任何想法,@Kato? – lowe0292 2015-01-27 22:15:03

+0

在问题中没有足够的代码来帮助您找出为什么它被调用的次数不止一次,除了auth方法可能被多次调用的事实以及每次调用每条记录时都会调用该方法负载。我敢肯定,这个游戏的一些变种正在发挥作用,但没有[mcve](http://stackoverflow.com/help/mcve),很难更具体。 – Kato 2015-01-28 14:53:57

+0

对不起@加藤,我打扫了一下代码,试图让它更加mcv。这是[gist](https://gist.github.com/lowe0292/fa3737fdabdff4059629)。谢谢! – lowe0292 2015-01-29 15:45:40

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', '[email protected]', 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

谢谢。这解决了我的问题。 – 2017-03-29 20:03:21

+1

固定矿井也.. – satheeshwaran 2017-04-14 17:29:46

相关问题