Firebase child_added for new items only

前端 未结 5 1168
北恋
北恋 2020-12-15 18:46

I am using Firebase and Node with Redux. I am loading all objects from a key as follows.

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


        
相关标签:
5条回答
  • 2020-12-15 18:49

    there was also another solution: get the number of children and extract that value: and it's working.

    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")
              });
         });
    
    0 讨论(0)
  • 2020-12-15 18:51

    Although the limit method is pretty good and efficient, but you still need to add a check to the child_added for the last item that will be grabbed. Also I don't know if it's still the case, but you might get "old" events from previously deleted items, so you might need to watch at for this too.

    Other solutions would be to either:

    Use a boolean that will prevent old added objects to call the callback

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

    The disadvantage of this method is that it would imply getting events that will do nothing but still if you have a big initial list might be problematic.

    Or if you have a timestamp on your invites, do something like

    firebaseDb.child('invites')
      .orderByChild('timestamp')
      .startAt(Date.now())
      .on('child_added', snapshot => {
      // do
    })
    
    0 讨论(0)
  • 2020-12-15 18:53

    If your document keys are time based (unix epoch, ISO8601 or the firebase 'push' keys), this approach, similar to the second approach @balthazar proposed, worked well for us:

    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
    });
    
    0 讨论(0)
  • 2020-12-15 19:05

    I have solved the problem using the following method.

    firebaseDb.child('invites').limitToLast(1).on('child_added', cb)
    firebaseDb.child('invites').on('child_changed', cb)
    

    limitToLast(1) gets the last child object of invites, and then listens for any new ones, passing a snapshot object to the cb callback.

    child_changed listens for any child update to invites, passing a snapshot to the cb

    0 讨论(0)
  • 2020-12-15 19:11

    I solved this by ignoring child_added all together, and using just child_changed. The way I did this was to perform an update() on any items i needed to handle after pushing them to the database. This solution will depend on your needs, but one example is to update a timestamp key whenever you want the event triggered. For example:

    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 })
    
    0 讨论(0)
提交回复
热议问题