Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Android ChildEventListener Triggered onChildRemoved() before onChildAdded() When new data added

I am adding new data to Firebase as following code

updateChildren(childUpdates, new DatabaseReference.CompletionListener() {
        @Override
        public void onComplete(DatabaseError databaseError,   DatabaseReference databaseReference) {

        }
}

And following code for ChildEventListener

fb.child(Organizations.class.getSimpleName().toLowerCase()).limitToLast(1).addChildEventListener(crudListener);

ChildEventListener crudListener = new ChildEventListener() {

        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            Log.e(TAG,"onChildAdded "+ dataSnapshot.toString()+" \n String "+s);
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            Log.e(TAG,"onChildChanged "+ dataSnapshot.toString()+" \n String "+s);
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            Log.e(TAG,"onChildRemoved "+ dataSnapshot.toString());
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {
            Log.e(TAG,"onChildAdded "+ dataSnapshot.toString()+" \n String "+s);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

};

issue is when I am creating new data then onChildRemoved() triggered before onChildAdded()

I am not removing any child but onChildRemoved() triggered every time when new child is created

following Web(javascript) code it's working fine

 firebase.initializeApp(config);


 var commentsRef = firebase.database().ref('organizations').limitToLast(1);
 commentsRef.on('child_added', function(snap) {
    $('pre').text("child_added: "+JSON.stringify(snap.val(), null, 2));
 });

 commentsRef.on('child_changed', function(snap) {
    $('pre').text("child_changed: "+JSON.stringify(snap.val(), null, 2));
 });

 commentsRef.on('child_removed', function(snap) {
    $('pre').text("child_removed: "+JSON.stringify(snap.val(), null, 2));
 });

here is my Database structure. I am creating new child under organizations

enter image description here

Pleaes help me how to fix this issue

like image 386
Munish Kapoor Avatar asked Oct 24 '25 01:10

Munish Kapoor


1 Answers

You mentioned you're using li‌mitToLast(1) when attaching crudListener. That's actually how it works.

from Quer#limitToLast() reference

The limitToLast() method is used to set a maximum number of children to be synced for a given callback. If we set a limit of 100, we will initially only receive up to 100 child_added events. If we have less than 100 messages stored in our database, a child_added event will fire for each message. However, if we have over 100 messages, we will only receive a child_added event for the last 100 ordered messages. As items change, we will receive child_removed events for each item that drops out of the active list, so that the total number stays at 100.

If you use li‌​mitToLast(1), the onChildRemoved() will be called if a new child is inserted to maintain the limit (which is 1), and then onChildAdded() called the new child.

If you don't want this behavior, remove the li‌​mitToLast(1) method

EDIT: If you want to keep using limitToLast(1), then you have to do checking if an organization entry is really removed from the database or it's from the limit behavior.

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
    dataSnapshot.getRef().addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (!dataSnapshot.exists()) {
                // remove this organization item from the RecyclerView
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}
like image 63
Wilik Avatar answered Oct 26 '25 15:10

Wilik