2012-08-03 122 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(),所以不需要捕获空的数据。