how to discard initial data in a Firebase DB

I'm making a simple app that informs a client that other clients clicked a button. I'm storing the clicks in a Firebase (db) using:

db.push({msg:data});

All clients get notified of other user's clicks with an on, such as

db.on('child_added',function(snapshot) { 
  var msg = snapshot.val().msg; 
});

However, when the page first loads I want to discard any existing data on the stack. My strategy is to call db.once() before I define the db.on('child_added',...) in order to get the initial number of children, and then use that to discard that number of calls to db.on('child_added',...).

Unfortunately, though, all of the calls to db.on('child_added',...) are happening before I'm able to get the initial count, so it fails.

How can I effectively and simply discard the initial data?


Solution 1:

For larger data sets, Firebase now offers (as of 2.0) some query methods that can make this simpler.

If we add a timestamp field on each record, we can construct a query that only looks at new values. Consider this contrived data:

{
  "messages": {
     "$messageid": {
        "sender": "kato",
        "message": "hello world"
        "created": 123456  // Firebase.ServerValue.TIMESTAMP
     }
  }
}

We could find messages only after "now" using something like this:

var ref = new Firebase('https://<your instance>.firebaseio.com/messages');

var queryRef = ref.orderBy('created').startAt(Firebase.ServerValue.TIMESTAMP);

queryRef.on('child_added', function(snap) {
  console.log(snap.val());
});

Solution 2:

If I understand your question correctly, it sounds like you only want data that has been added since the user visited the page. In Firebase, the behavior you describe is by design, as the data is always changing and there isn't a notion of "old" data vs "new" data.

However, if you only want to display data added after the page has loaded, try ignoring all events prior until the complete set of children has loaded at least once. For example:

var ignoreItems = true;
var ref = new Firebase('https://<your-Firebase>.firebaseio.com');
ref.on('child_added', function(snapshot) {
  if (!ignoreItems) {
    var msg = snapshot.val().msg;
    // do something here
  }
});
ref.once('value', function(snapshot) {
  ignoreItems = false;
});

The alternative to this approach would be to write your new items with a priority as well, where the priority is Firebase.ServerValue.TIMESTAMP (the current server time), and then use a .startAt(...) query using the current timestamp. However, this is more complex than the approach described above.