seanpj
seanpj

Reputation: 6755

ChildEventListener inconsistency?

I've been playing with the Firebase Android Api and discovered this feature (that appears to me as inconsistency). I would like to solicit an opinion and/or a solution for a problem it causes in my scenario.

In the Android app, I establish a standard 'ChildEventListener' in this form:

new Firebase("https://[MYTEST].firebaseio.com/").addChildEventListener(
  new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot data, String prev) {
      Log.i("_", "add " + data);
    }
    @Override
    public void onChildChanged(DataSnapshot data, String prev) {
      Log.i("_", "chg " + data);
    }
    @Override
    public void onChildRemoved(DataSnapshot data) {
      Log.i("_", "del " + data);
    }
    @Override
    public void onChildMoved(DataSnapshot data, String prev) {
      Log.i("_", "mov " + data);
    }
    @Override
    public void onCancelled(FirebaseError err) {
      Log.i("_", "err " + err.getMessage());
    }
  }
);

Works like a charm, catching all events I can throw on it from the Firebase Dashboard.

Next:

I understand that this behavior may be by design, but it presents a problem even if I keep a local list of nodes and simple differential may give me the set of deleted nodes. But the fact, that an empty list of nodes generates no 'onChildAdded()' event makes it difficult to place the code that would calculate deleted nodes.

I assume there is another way to get around this 'deletion while dead' problem, please nudge me in the right direction.

Upvotes: 2

Views: 253

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598847

Summary: the Firebase database synchronizes state. Unlike message passing mechanisms it does not synchronize state changes.

When you start an app that has no data from the Firebase database cached, the Firebase API synchronizes the minimal data that your app needs to get synchronized with the stored information. So you'll get a child_added event for any data that exists on the server at that time.

If your app already has previous information from the database when it connects (such as when you've used Firebase's disk persistence or when your connection is restored without an app restart), the API will fire the events that are necessary to get the local version of the data up to date with the server. So in that case, you may see child_added, child_changed, child_moved and child_removed events.

There is no guarantee that state changes when your client was not connected are transmitted.

State synchronization in practice

An example of this:

  • go online
  • get all data
  • go offline
  • another user adds value A
  • another user removes value A
  • go online again

Your app will now not receive any indication that value A ever existed. This is simply the way state synchronization works.

Storing state changes, instead of state

If your app requires that each client knows of every state change, you should store the actual state changes in the database.

  • go online
  • get all data
  • go offline
  • another user writes record "add value A"
  • another user writes record "remove value A"
  • go online again

The client will now receive all state changes, because you stored those in the database.

Typically you'll also want to run a trusted process that aggregates all the state change records into a single "current state" again for faster access.

Upvotes: 1

Related Questions