Firebase child_added仅适用于新项目

Lee*_*Lee 19 javascript events firebase firebase-realtime-database redux

我正在使用Firebase和Node with Redux.我按如下方式从密钥加载所有对象.

firebaseDb.child('invites').on('child_added', snapshot => {
})
Run Code Online (Sandbox Code Playgroud)

这种方法背后的想法是我们从数据库中获取有效负载,并且只使用一个动作通过Reducers更新我的本地数据存储.

接下来,我需要收听关键邀请的任何新的更新的孩子.然而,现在的问题是child_added事件触发所有现有密钥以及新添加的密钥.我不想要这种行为,我只需要新密钥,因为我检索了现有数据.

我知道child_added通常用于这种类型的操作,但是,我希望减少触发的动作数量,并因此触发呈现.

实现这一目标的最佳模式是什么?

谢谢,

Lee*_*Lee 17

我用下面的方法解决了这个问题.

firebaseDb.child('invites').limitToLast(1).on('child_added', cb)
firebaseDb.child('invites').on('child_changed', cb)
Run Code Online (Sandbox Code Playgroud)

limitToLast(1)获取邀请的最后一个子对象,然后侦听任何新对象,将快照对象传递给cb回调.

child_changed侦听要邀请的任何子更新,将快照传递给cb


Bal*_*zar 14

虽然限制方法非常好而且效率很高,但您仍然需要child_added为最后一个要抓取的项添加一个检查.此外,我不知道是否仍然如此,但您可能会从之前删除的项目中获得"旧"事件,因此您可能还需要注意这一点.

其他解决方案是:

使用一个布尔值来阻止旧的添加对象调用回调

let newItems = false

firebaseDb.child('invites').on('child_added', snapshot => {
  if (!newItems) { return }
  // do
})

firebaseDb.child('invites').once('value', () => {
  newItems = true
})
Run Code Online (Sandbox Code Playgroud)

这种方法的缺点是它会暗示获取什么都不会做的事情,但如果你有一个很大的初始列表可能会有问题.

或者,如果您的邀请中有时间戳,请执行类似的操作

firebaseDb.child('invites')
  .orderByChild('timestamp')
  .startAt(Date.now())
  .on('child_added', snapshot => {
  // do
})
Run Code Online (Sandbox Code Playgroud)