我正在使用Firebase和Node with Redux。我按如下方式从密钥加载所有对象。
firebaseDb.child('invites').on('child_added', snapshot => {
})
这种方法背后的想法是我们从数据库获得一个有效负载,并且只使用一个动作通过Reducers更新我的本地数据存储。
接下来,我需要听取密钥邀请的任何 NEW 或 UPDATED 子项。 但是,现在的问题是 child_added 事件会触发所有现有密钥以及新添加的密钥。我不想要这种行为,我只需要新密钥,因为我检索了现有数据。
我知道child_added通常用于这种类型的操作,但是,我希望减少触发的操作数量,并因此触发呈现。
实现这一目标的最佳模式是什么?
谢谢,
答案 0 :(得分:16)
我使用以下方法解决了这个问题。
firebaseDb.child('invites').limitToLast(1).on('child_added', cb)
firebaseDb.child('invites').on('child_changed', cb)
limitToLast(1)获取邀请的最后一个子对象,然后侦听任何新对象,将快照对象传递给cb回调。
child_changed 侦听要邀请的任何子更新,将快照传递给cb
答案 1 :(得分:14)
尽管限制方法非常好且有效,但您仍需要为child_added
添加一个检查,以获取最后一个要抓取的项目。此外,我不知道它是否仍然如此,但你可能已经老了"来自之前已删除项目的事件,因此您可能还需要注意这一点。
其他解决方案是:
使用一个布尔值来阻止旧的添加对象调用回调
let newItems = false
firebaseDb.child('invites').on('child_added', snapshot => {
if (!newItems) { return }
// do
})
firebaseDb.child('invites').once('value', () => {
newItems = true
})
这种方法的缺点是,如果你有一个很大的初始列表可能会有问题,那就意味着得到什么都不会做的事情。
或者,如果您的邀请中有时间戳,请执行以下操作:
firebaseDb.child('invites')
.orderByChild('timestamp')
.startAt(Date.now())
.on('child_added', snapshot => {
// do
})
答案 2 :(得分:1)
还有另一个解决方案: 得到孩子的数量并提取该值: 它正在工作。
var ref = firebaseDb.child('invites')
ref.once('value').then((dataSnapshot) => {
return dataSnapshot.numChildren()
}).then((count) =>{
ref .on('child_added', (child) => {
if(count>0){
count--
return
}
console.log("child really added")
});
});
答案 3 :(得分:0)
我通过一起忽略child_added
并仅使用child_changed
来解决这个问题。我这样做的方法是对我需要处理后>>将它们推送到数据库的任何项目执行update()
。此解决方案将取决于您的需求,但一个示例是在您希望触发事件时更新时间戳键。例如:
var newObj = { ... }
// push the new item with no events
fb.push(newObj)
// update a timestamp key on the item to trigger child_changed
fb.update({ updated: yourTimeStamp })
答案 4 :(得分:0)
如果您的文档密钥是基于时间的(unix epoch,ISO8601或firebase'push'密钥),则此方法与@balthazar建议的第二种方法相似,对我们来说效果很好:
const maxDataPoints = 100;
const ref = firebase.database().ref("someKey").orderByKey();
// load the initial data, up to whatever max rows we want
const initialData = await ref.limitToLast(maxDataPoints).once("value")
// get the last key of the data we retrieved
const lastDataPoint = initialDataTimebasedKeys.length > 0 ? initialDataTimebasedKeys[initialDataTimebasedKeys.length - 1].toString() : "0"
// start listening for additions past this point...
// this works because we're fetching ordered by key
// and the key is timebased
const subscriptionRef = ref.startAt(lastDataPoint + "0");
const listener = subscriptionRef.on("child_added", async (snapshot) => {
// do something here
});