2015-01-26 106 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

相關問題