How to only get new data without existing data from a Firebase?

I have a node in Firebase getting continually updated with information from a logfile. The node is lines/ and each child of lines/ is from a post() so it has a unique ID.

When a client first loads, I want to be able to grab the last X number of entries. I expect I'll do this with once(). From then on, however, I want to use an on() with child_added so that I get all new data. However, child_added gets all data stored in the Firebase and, after the initial setup, only want the new stuff.

I see that I can add a limitToLast() on the on(), but, if I say limitToLast(1) and a flood of entries come in, will my app still get all the new entries? Is there some other way to do this?

Answers:

Answer

You need to include a timestamp property and run a query.

// Get the current timestamp
var now = new Date().getTime();
// Create a query that orders by the timestamp
var query = ref.orderByChild('timestamp').startAt(now);
// Listen for the new children added from that point in time
query.on('child_added', function (snap) { 
  console.log(snap.val()
});

// When you add this new item it will fire off the query above
ref.push({ 
  title: "hello", 
  timestamp: Firebase.ServerValue.TIMESTAMP 
});

The Firebase SDK has methods for ordering, orderByChild() and methods for creating a range startAt(). When you combine the two you can limit what comes back from Firebase.

Answer

You have the right idea. child_added should be called only for the new nodes. Without source code it's hard to tell why you get all the data in your child_added event.

You can check the chat demo app to see how they load new chat messages. The use case sounds similar.

https://github.com/firebase/firechat/blob/master/src/js/firechat.js#L347

Answer

Here's temporary but quick solution:

// define a boolean
var bool = false;

// fetch the last child nodes from firebase database
ref.limitToLast(1).on("child_added", function(snap) {
    if (bool) {
        // all the existing child nodes are restricted to enter this area
        doSomething(snap.val())
    } else {
        // set the boolean true to doSomething with newly added child nodes
        bool = true;
    }
});

Disadvantage: It will load all the child nodes.

Advantage: It will not process existing child nodes but just the newly added child nodes.

limitToLast(1) will do the work.

Answer

I think there is a problem in @David East's solution. He is using the local timestamp which may cause problem if the time is not accurate in client device. Here is my suggested solution (iOS Swift):

  • Using observeSingleEvent to get the complete data set
  • Then returned it in reversed order by reversed()
  • Get the last timestamp by for example data[0].timestamp
  • Using queryStarting for timestamp

     self._dbref.queryOrdered(byChild: "timestamp").queryStarting(atValue: timestamp+1)
         .observe(.childAdded, with: {
            snapshot in
            print(snapshot.value)
      })
    

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.