Why are Firebase events "child_added" displayed out of order?

I have two "limit" requests on the same path. First load "limit (1)" and then download "limit (50)".

When I load the second request, the child_added events do not fire in order. Instead, the last item in the list (the one returned by the limit (1)) is first started, and then all other elements are started in order, for example:

**Limit 1:** new Firebase(PATH).limit(1).on('child_added', ...) Message 5 **Limit 2:** new Firebase(PATH).limit(50).on('child_added', ...) Message 5 Message 1 Message 2 Message 3 Message 4 

I am confused why "Message 5" is called first in the second restriction operation. Why is this happening, and how can I fix it?

+6
source share
1 answer

I know this may seem strange, but this is actually the intended behavior.

To ensure that local events can fire immediately without contacting the server, Firebase does not guarantee that child_added events will always be fired in sort order.

If this is confusing, think of it this way: if you didn’t have an internet connection at all, and you set the limit (50) and then called push () in this link, you would expect the event to be fired immediately. However, when reconnecting to the server, it may turn out that before you clicked, other elements appeared on the server, which then will be triggered after the event for the one you added. In your example, the problem is with what data was cached locally, and not something written by the local client, but the same principle applies.

For a more detailed example of why you need to work this way, imagine 2 clients, A and B:

  • In standalone mode, client A calls push () and sets some data
  • In online mode, client B adds a child_added listener to read messages
  • Client B then calls push (). The message that it clicked fires the child_added event immediately locally.
  • Client A returns online. Firebase synchronizes the data, and client B receives the child_added event that is fired for that data.

Now note that even if the β€œClient A” message is added first in the list (since it has an earlier timestamp), the event fires second.

So, as you can see, you cannot always rely on the order of events to reflect the correct sorting order of Firebase children.

But don’t worry, you can still get your behavior! If you want the data to be displayed in the sort order, and not in the order the events arrived at your client, you have several options:

1) (Naive approach) Use the value event instead of child_added and redraw the entire list of elements each time it is fired using forEach. Value events only fire for complete data sets, so forEach always lists all events in order. There are a couple of lower levels of this approach: (1) value events do not fire until the initial state is downloaded from the server, so it will not work if the application is launched in "offline mode" until a network connection is established installed. (2) He inefficiently redraws everything for each change.

2) (best approach) Use the prevChildName argument in the to on () callback. In addition to the snapshot, the callback for on () is passed the name of the previous child in the request when the elements are placed in sort order. This allows you to display the children in the correct order, even if the events are disabled. See: https://www.firebase.com/docs/javascript/firebase/on.html

Note that prevChildName provides only the previous child in the request, and not in the entire Firebase location. Thus, the child at the beginning of the request will have a prevChildName value of null, even if the server has a child.

Our leader example shows one way to manipulate the DOM to ensure that things are displayed in the correct order. See: https://www.firebase.com/tutorial/#example/leaderboard

+9
source

All Articles