Firebase child_added仅限新项目

时间:2017-04-16 18:57:23

标签: javascript events firebase firebase-realtime-database redux

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

firebaseDb.child('invites').on('child_added', snapshot => {
})

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

接下来,我需要听取密钥邀请的任何 NEW UPDATED 子项。 但是,现在的问题是 child_added 事件会触发所有现有密钥以及新添加的密钥。我不想要这种行为,我只需要新密钥,因为我检索了现有数据。

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

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

谢谢,

5 个答案:

答案 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
});