2012-08-03 208 views
39

從火力地堡API:火力地堡child_added只能得到孩子添加

兒童補充:這一事件將再次爲每個初始子 在這個位置被觸發,它將再次每次都引發了新 孩子被添加。

一些代碼:

listRef.on('child_added', function(childSnapshot, prevChildName) { 
    // do something with the child 
}); 

但由於功能是爲每個孩子調用一次在這個位置,有沒有什麼辦法讓只有實際添加了孩子?

+10

爲什麼這種方法不能完成它所說的?它應該只做一件事 - 任何時候添加一個孩子都會觸發 - 僅此而已。 – 2017-03-04 22:32:24

+2

是的同意@Jose Browne。它令人困惑... – 2017-04-05 12:25:12

回答

29

要跟蹤的東西,因爲有些檢查站增加並不獲取以前的記錄,你可以使用endAt()limit()搶到最後一個記錄:

// retrieve the last record from `ref` 
ref.endAt().limit(1).on('child_added', function(snapshot) { 

    // all records after the last continue to invoke this function 
    console.log(snapshot.name(), snapshot.val()); 

}); 
+0

其實,我發現了一個更簡單的方法,因爲即使在達到limit()後,它仍然會通知您添加的事件。我相應地更新了我的答案。 – Kato 2012-08-03 07:38:09

+1

目前還不清楚你的意思。這隻適用於有序集合,但是如果您需要訂購別的東西(除了有序集合?)...另外,您的評論並不能幫助任何人瞭解如何在Firebase中獲得添加子項事件。 – Kato 2014-07-22 19:28:01

+1

回調函數僅對'ref.endAt()。limit(1)'返回的記錄觸發一次。它不會觸發該記錄後添加的其他新記錄。我正在用Angularfire 0.8測試這個。0 – Waseem 2014-09-10 20:22:25

28

limit()方法已經過時了。 limitToLast()limitToFirst()方法取代它。

// retrieve the last record from `ref` 
ref.limitToLast(1).on('child_added', function(snapshot) { 

    // all records after the last continue to invoke this function 
    console.log(snapshot.name(), snapshot.val()); 
    // get the last inserted key 
    console.log(snapshot.key()); 

}); 
+3

我已經嘗試了這種方法,但有一點需要注意:如果刪除了最後一條記錄,例如用戶發佈評論並將其刪除(這是一個錯誤),上面的.on()函數將被再次調用。我解決了添加時間戳並檢查添加的孩子是否少於一秒鐘,如果它較舊,它是舊記錄並且未被添加。爲此,請查看ref.child('。info') – DivZero 2015-10-17 13:51:50

+2

我不明白 - 這不就是最後一項嗎?那麼「綁定到這個事件後添加的項目」呢? – 2016-06-12 20:27:53

+0

是的想知道的一樣。它只獲得最後一個項目,然後不會觸發其他添加的事件。 – Orlando 2016-07-07 08:11:11

0

對我的邏輯是是具有價值 - 「狀態」的示例 - 其中需要決定是否是真正的新前被驗證或者是一個老唱片,然後我設置了「狀態」,以不同的

@Override 
     public void onChildAdded(DataSnapshot dataSnapshot, String previousChildKey) { 

       if(dataSnapshot.hasChildren()) { 

        String Id = (String) dataSnapshot.child("user_id").getValue(); 
        String status = (String) dataSnapshot.child("status").getValue(); 

        if (Id != null && Id.equals(storedId) && status != null && status.equals("created")) { 
         Log.d("INCOMING_REQUEST", "This is for you!"); 
         sessionsRef.child(dataSnapshot.getKey()).child("status").setValue("received"); 
        } 

       } 


     } 
0

Swift3解決方案:價值,所以我不在下一次得到它

您可以通過下面的代碼檢索以前的數據:

queryRef?.observeSingleEvent(of: .value, with: { (snapshot) in 
     //Your code 

    }) 

然後通過以下代碼觀察新數據。

queryRef?.queryLimited(toLast: 1).observe(.childAdded, with: { (snapshot) in 

//Your Code 

     }) 
1

我試了其他答案的方式,但至少爲最後一個孩子調用過一次。如果你的數據有時間鍵,你可以這樣做。

ref.orderByChild('createdAt').startAt(Date.now()).on('child_added', ... 
1

由於調用ref.push()方法,無需基於時間的數據生成路徑密鑰,這是我做的:

// Get your base reference 
const messagesRef = firebase.database().ref().child("messages"); 

// Get a firebase generated key, based on current time 
const startKey = messagesRef.push().key; 

// 'startAt' this key, equivalent to 'start from the present second' 
messagesRef.orderByKey().startAt(startKey) 
.on("child_added", 
    (snapshot)=>{ /*Do something with future children*/} 
); 

注意,沒有什麼實際寫入到基準(或「鑰匙」),其返回ref.push(),所以不需要捕獲空的數據。