googlearchive / firebase-util

An experimental toolset for Firebase
http://firebase.github.io/firebase-util
MIT License
276 stars 67 forks source link

on('child_changed',...) is being called many times when remove/re-add a record key #36

Closed AaronJPA closed 9 years ago

AaronJPA commented 9 years ago

on('child_changed',...) is being called many times when it probably shouldn't.

I'm opening four different issues because I'm not sure if they are related and, if they are not, they can be fixed separately. However, I used the same Plunker to simulate all of them, so it is a little bigger than usual. I tried to explain everything in the comments, but if something is not clear enough, just let me know.

http://plnkr.co/edit/Y0mp2XDtSQ0Pz9ClXctZ

katowulf commented 9 years ago

Thanks for the report. Essentially, the only difference I see between this and the current SDK behavior is that the child_changed event is triggered once for each merged path in some cases. It fires fairly consistently with the API in other regards (e.g. deleting an item in Firebase triggers a child_changed with a null value).

I don't see any great way to improve on the child_changed calls within the current limitations of the API. Essentially, since changing or deleting a record requires iterating the merged nodes and applying the change to each, and since there is no atomic way to do this in Firebase, we'll get the locally triggered events individually.

I looked at some options for trying to debounce the calls and wait for all the merged nodes to update before triggering, but timing of updates and ordering of records quickly grew too complex to predict.

I did make a couple adjustments that will help. One was to ensure that records will not trigger value events if the value hasn't changed since the last event. That should cut down the frequency of the messages a bit. I'll check that in shortly.

katowulf commented 9 years ago

Found some more clues while working on the filter/value issue. So this appears to be an issue with listeners getting attached multiple times. After records are deleted, the event listeners are not properly being removed. So when the record is recreated, it triggers child_changed events twice.

Came to this conclusion after realizing that the behavior disappears if I comment out all but any given write event. It's not any specific item but the culmination of items.