Firebase child_ added 只添加孩子
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11788902/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Firebase child_added only get child added
提问by Matt Robertson
From the Firebase API:
来自 Firebase API:
Child Added: This event will be triggered once for each initial child at this location, and it will be triggered again every time a new child is added.
Child 添加:此事件会针对该位置的每个初始子项触发一次,每次添加新子项时都会再次触发。
Some code:
一些代码:
listRef.on('child_added', function(childSnapshot, prevChildName) {
// do something with the child
});
But since the function is called once for each child at this location, is there any way to get only the child that was actually added?
但是由于该函数在这个位置为每个孩子调用一次,有没有办法只获取实际添加的孩子?
采纳答案by Kato
To track things added since some checkpoint without fetching previous records, you can use endAt()and limit()to grab the last record:
要跟踪自某个检查点以来添加的内容而不获取以前的记录,您可以使用endAt()和limit()获取最后一条记录:
// retrieve the last record from `ref`
ref.endAt().limitToLast(1).on('child_added', function(snapshot) {
// all records after the last continue to invoke this function
console.log(snapshot.name(), snapshot.val());
});
回答by tibeoh
limit()method is deprecated. limitToLast()and limitToFirst()methods replace it.
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());
});
回答by smackjax
Since calling the ref.push()method without data generates path keys based on time, this is what I did:
由于调用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*/}
);
Note that nothing is actually written to the reference(or 'key') that ref.push()returned, so there's no need to catch empty data.
请注意,实际上没有将任何内容写入返回的引用(或“键”)ref.push(),因此无需捕获空数据。
回答by Juntae
I tried other answers way but invoked at least once for last child. If you have a time key in your data, you can do this way.
我尝试了其他答案方式,但至少为最后一个孩子调用了一次。如果您的数据中有时间键,您可以这样做。
ref.orderByChild('createdAt').startAt(Date.now()).on('child_added', ...
回答by Milligator
Swift3 Solution:
Swift3 解决方案:
You can retrieve your previous data through the following code:
您可以通过以下代码检索以前的数据:
queryRef?.observeSingleEvent(of: .value, with: { (snapshot) in
//Your code
})
and then observe the new data through the following code.
然后通过以下代码观察新数据。
queryRef?.queryLimited(toLast: 1).observe(.childAdded, with: { (snapshot) in
//Your Code
})
回答by Zain
Since .limitToLast()method still called for the last item in your list even if it's not a new item, we can solve it as below:
由于.limitToLast()方法仍然调用列表中的最后一个项目,即使它不是一个新项目,我们可以如下解决它:
The idea is:
这个想法是:
Create a List that keeps your firebase items; and whenever onChildAdded(...)method is called, check if the incoming datasnapshot is in your list or not; if not, then it's new data
创建一个列表来保存您的 Firebase 项目;每当onChildAdded(...)调用方法时,检查传入的数据快照是否在您的列表中;如果不是,那么它是新数据
In order to achieve this you must meet below conditions:
为了实现这一点,您必须满足以下条件:
Have a unique value for each item. (this can be achieved when you add items into Firebase by using the key generated by
.push()method.Override
.equals()method of your model class in order to fulfill the comparison based on this unique value.
每个项目都有一个独特的价值。(这可以在您使用
.push()方法生成的密钥将项目添加到 Firebase 时实现。覆盖
.equals()模型类的方法以完成基于此唯一值的比较。
Code snippet
代码片段
Note: I put the list of items in the model class as of my choice.
注意:我根据自己的选择将项目列表放在模型类中。
Model class
模型类
public class MyModel {
private String id; // unique ID from model to another
public static List<MyModel> sItems; // my tracked items
// reset of fields ...
public MyModel() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public boolean equals(@Nullable Object o) {
// If the object is compared with itself then return true
if (o == this) {
return true;
}
// Check if o is an instance of MyModel or not
if (!(o instanceof MyModel)) {
return false;
}
// typecast o to MyModel so that we can compare data members
MyModel model = (MyModel) o;
// Compare data based on the unique id
return (model.id).equals(id);
}
}
Firebase listener
Firebase 侦听器
private ChildEventListener mChildEventListener = new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
Log.d(TAG, "ChildEventListener: onChildAdded()");
MyModel deal = dataSnapshot.getValue(MyModel.class);
if (!MyModel.sItems.contains(model)) {
// Here you'll receive only the new added values
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
Log.d(TAG, "ChildEventListener: onChildChanged()");
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
Log.d(TAG, "ChildEventListener: onChildRemoved()");
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
Log.d(TAG, "ChildEventListener: onChildMoved()");
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG, "ChildEventListener: onCancelled()");
}
};
Then limit to last
然后限制到最后
databaseReference.limitToLast(1).addChildEventListener(mChildEventListener);

