child_added gets triggered after remove

两盒软妹~` 提交于 2021-02-20 18:50:48

问题


I've created this handler to watch for new children being created. This little trick stops the child_added event from triggering my code on each page load. Instead it only gets triggered when something is actually added.

  // Listen for new rooms being created
  var first_room_added_after_load = true;
  this._roomRef.endAt().limit(1).on('child_added', function(snapshot){
      if (first_room_added_after_load) { // we want to skip the first room, because it will already exist
          first_room_added_after_load = false;
          return;
      }
      else {
          this._onCreateRoom(snapshot);
      }
  }, this);

That said, when I call remove() on a node in _roomRef then child_added is triggered for a node that already exists. Any hints as to why, and how to stop it?

I should also mention this only seems to happen if I remove something that was created after something else already in the list. If I remove the older items first, then child_added is not triggered.


回答1:


You seem to think the endAt() uses a timestamp for comparison, so that it only returns new children. But that's simply not how it works. From the Firebase documentation for endAt:

If no arguments are provided, the ending point will be the end of the data.

With your code:

this._roomRef.endAt().limit(1)

You're creating a query that is set to always return a single child. The condition is that the child was created after you created the query.

A query is like a sliding window over the child nodes in your Firebase ref: it will always contain (at most) one child, a child that was created after you created your query.

Example

Say you have these children when you create the query:

child1
child2
child3 <!-- last child present when creating the endAt() query -->

By using endAt query will be "rooted" after child3. So it will not fire any events for child1, child2 and child3.

Say you add a new child:

child1
child2
child3 <!-- last child present when creating the endAt() query -->
child4

The query will a child_added event for child4.

Now if we add another child:

child1
child2
child3 <!-- last child present when creating the endAt() query -->
child4
child5

The query will fire a child_removed for child4 and child_added for child5. Note that child4 was not actually removed from your Firebase, it just disappeared from the query results (since you asked to limit the number of results to just one).

When we now remove the latest child, we end up with:

child1
child2
child3 <!-- last child present when creating the endAt() query -->
child4

And the query will fire a child_removed for child5 and child_added for child4. This again comes from the fact that your query is set to always contain (at most) one node that was added after child3.

How to get what you want

It seems like you only want to get child_added once for newly added children. In that case I would not use a limit on the query, but instead I would set the timestamp that the room was created as its priority:

this._roomRef.push({
    /* whatever properties you need for a room */, 
    '.priority': Firebase.ServerValue.TIMESTAMP 
})

Then you can simply start the query at that priority.

this._roomRef.startAt(Date.now()).on('child_added', ...



回答2:


I found a tricky solution for this . Let's suppose you are getting messages with value like msg-txt , timestamp , userid When you get the first messages using child_added you need to store the latest message timestamp into a global variable then for every new chils_added just compare the two timestamps .

If the message timestamp > the global timestamp Then return the message and save its timestamp to global timestamp.

Hope this will help



来源:https://stackoverflow.com/questions/25235283/child-added-gets-triggered-after-remove

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!