2

Here's my scenario. When child is added via a browser event post page load, I want to indicate it in the title. But on page load, child added is called as well.

How can I differentiate the initial child added vs one where a new entry has been actually added.

Thanks, Tim

Itumac
  • 647
  • 2
  • 7
  • 16

3 Answers3

7

Firebase very intentionally does not distinguish "initial" data from "new" data. This allows for much simpler development in most cases, because you only have to write one set of logic for your data, rather than handling both the initial data case and the new data case.

I can see how you would want the distinction in this case. I'm not sure exactly what you're doing, but if you're building a chat application, you might want to flash the title based on the timestamp of the most recent message rather than whether or not it's a "new" message. This would allow the title to flash on page load if a message was sent slightly before the page was loaded, which may be desirable. In some other cases, you may actually want to flash the title for unread data, and you may want to consider marking children as "read" and flashing the title only for children that show up without the "read" bit. This would allow things to work seamlessly across page refreshes.

If you absolutely need to know when "new" data shows up, you could try using "once" with a "value" event type to get the data, and then use "on" with a startAt query and a "child_added" event type to display new data after that. It would look something like this:

var data = new Firebase(...);
data.once("value", function(d) {
  //TODO: display initial state...

  data.startAt(null, <last id in snapshot>).on("child_added", function(newMessSnapshot) {
    //TODO: render new child and flash title bar.
  }
}

Or if you want to do it the really simple way, you could just set a timer so that the title won't flash for any messages received within the first N seconds of page load.

Hope that helps!

Andrew Lee
  • 10,127
  • 3
  • 46
  • 40
  • Your second plan is exactly what I am looking for. I don't want to manage read states. (My app is a real-time posting platform. I expect people to open it and keep it open but blur to other actions on their PC. If a new post comes in, I want the title to show an alert) – Itumac Oct 12 '12 at 03:06
  • Great! Can you mark the answer as the correct solution so others can find it? – Andrew Lee Oct 12 '12 at 03:11
  • Y'know. idea 3 is starting to appeal to me. Not to the developer in me but the make an app guy in me. – Itumac Oct 12 '12 at 03:29
4

You can set up a call that only receives new events rather than ones already existing using the approach from this SO question.

So basically, call .on('child_added'...) with endAt and limit. You still get one entry (the last one), which you can just ignore:

// connect to firebase
var fb = new Firebase(...);

// retrieve the last record from `ref` (endAt() tells it to start at the end)
var first = true;
fb.child('table_name').endAt().limit(1).on('child_added', function(snapshot) {

   if( first ) {
       // ignore the first snapshot, which is an existing record
       first = false;
       return;
   }

   // all records after the last continue to invoke this function
   console.log(snapshot.name(), snapshot.val());

});
Community
  • 1
  • 1
Kato
  • 40,352
  • 6
  • 119
  • 149
  • what if i have **up to** 5 last notifications that are 'old' on initial page load. and now i want to listen only to new notifications. because when notification comes in i am shooting ajax call to backend. so in order to avoid every time on page load do up to 5 ajax calls to backend i need to do only one ajax call to backend when page was loaded and then while the page is on then do ajax request on every new child added. i assume here would work the timestamp comparing – Skyzer May 16 '15 at 07:20
  • You're probably looking for this: http://stackoverflow.com/questions/18270995/how-to-retreive-only-new-data – Kato May 16 '15 at 23:46
3

I thought I would update Kato's answer as Datasnapshot.name() and limit have now both been depreciated.

I decided to make it a bit more simple as well ;)

  // connect to firebase
  var fb = new Firebase("https://your-firebase-ref/");
  var firstTime = false;

  fb.limitToLast(1).on('child_added', function(snapshot) {
    if (firstTime) {
      console.log(snapshot.key(), snapshot.val());
    };
    firstTime = true;
  });

I hope this helps

Jon
  • 1,328
  • 1
  • 11
  • 11
  • I'd ping you too, @Jon. What if I `limitToLast(5)` so i can have **up to 5** notifications on page load. A counter wouldn't help in this case, because I don't know exact number of objects to expect on page load, it could be anything from 0 to 5. Also I asked same question under @Kato answer – Skyzer May 16 '15 at 07:28