已添加Firebase子项\u仅获取已添加的子项
从Firebase API: 添加的子项:此事件将为每个初始子项触发一次 在该位置,每次新的 添加了child 一些代码:已添加Firebase子项\u仅获取已添加的子项,firebase,Firebase,从Firebase API: 添加的子项:此事件将为每个初始子项触发一次 在该位置,每次新的 添加了child 一些代码: listRef.on('child_added', function(childSnapshot, prevChildName) { // do something with the child }); 但是,由于此位置的每个子项都会调用一次函数,因此有没有办法只获取实际添加的子项?要跟踪自某个检查点以来添加的内容而不获取以前的记录,可以使用endAt()和lim
listRef.on('child_added', function(childSnapshot, prevChildName) {
// do something with the child
});
但是,由于此位置的每个子项都会调用一次函数,因此有没有办法只获取实际添加的子项?要跟踪自某个检查点以来添加的内容而不获取以前的记录,可以使用
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());
});
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());
});
Swift3解决方案:
您可以通过以下代码检索以前的数据:
queryRef?.observeSingleEvent(of: .value, with: { (snapshot) in
//Your code
})
然后通过以下代码观察新数据
queryRef?.queryLimited(toLast: 1).observe(.childAdded, with: { (snapshot) in
//Your Code
})
我尝试了其他的答案,但最后一个孩子至少用了一次。如果您的数据中有一个时间键,您可以这样做
ref.orderByChild('createdAt').startAt(Date.now()).on('child_added', ...
由于在没有数据的情况下调用
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()
返回的引用(或“键”)实际上没有写入任何内容,因此不需要捕获空数据 由于.limitToLast()
方法仍然为列表中的最后一项调用,即使它不是新项,我们可以按如下方式解决它:
想法是:
创建保存firebase项目的列表;每当调用onchildaded(…)
方法时,检查传入的datasnapshot是否在列表中;如果不是,则是新数据
为了实现这一点,您必须满足以下条件:
.push()
方法生成的键将项目添加到Firebase中来实现.equals()
方法,以便基于此唯一值进行比较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);
}
}
然后限制到最后
databaseReference.limitToLast(1).addChildEventListener(mChildEventListener);
事实上,我发现了一种更简单的方法,因为即使在达到limit()之后,它也会继续通知您添加的事件。我已经相应地更新了我的答案。不清楚您的意思。这只适用于有序集,但如果您需要为其他内容(除了有序集之外)排序,它会起作用…此外,您的注释也不能帮助任何人理解如何在Firebase中获取子添加事件。回调函数仅对
ref.endAt().limit(1)返回的记录激发一次
。它不会为在该记录之后添加的其他新记录触发。我正在使用Angularfire 0.8.0Kato对GitHub进行测试。它对最后一个子项(在添加新子项之前)仍会调用回调一次,对吗?我尝试过这种方法,但有一件事需要注意:如果最后一条记录被删除,例如,用户发布一条评论并立即删除(例如,这是一个错误),请参见上面的函数将被再次调用。我解决了添加时间戳并检查所添加的子项是否小于1秒,如果较旧,则为旧记录且未添加。为此,请查看ref.child('.info')我不了解它-这不就是最后一项吗?关于“仅在绑定到此事件后添加的项”如何?是的,我也这么想。它只获取最后一条消息一次,然后就不会为其他添加的事件触发。@DivZero我试着按照你说的做,但由于我的聊天在android和iOS之间共享,所以无法工作,因为来自其他设备的消息延迟较长。它也容易出错,所以我检查了新消息是否已经在聊天中,我如果是,我不添加它。child_added
函数采用两个参数,snapshot
和prevChildKey
,这种方法prevChildKey
总是空的。我使用了ref.endAt().on('child_added',function(snapshot,prev){})
为什么这个方法不按照它说的那样做呢?它应该只做一件事——在添加孩子时触发——别的什么都不做。是的,同意@jose Browne。它让人困惑…[2018-04-27T23:58:32.727Z]@ FialBase/Dave:FielBase警告:使用未指定的索引。您的数据将在客户端上下载和筛选。考虑添加“.index”:“CealDATA”。at/sms记录到您的安全规则中以获得更好的性能。您能否在此基础上进行扩展,以便.childAdded不会添加所有消息。因此,如果我使用的是数组,我希望在observeSingleEvent中查询最后100个,然后在之后侦听.chlidded和.childRemoved中的所有新事件。如果我正确理解您的问题,您希望检索吗在开始的最后100条记录,然后你想要监听更新。基于谷歌文档,你可以使用“queryLimitedToLast”观察者。
databaseReference.limitToLast(1).addChildEventListener(mChildEventListener);