Islam Ahmed
Islam Ahmed

Reputation: 736

Why onChildAdded is fired multiple times?

I have a problem with my code, I don't know if I get it because of onChildAdded or RecyclerView

Simply I want to display messages Inbox on RecyclerView that contains all messages I received from other users, each message contains the last message sent and information about senders such as his name and photo.

Like this

This is my structure

Messages
  Receiver_UID
     Sender_UID
        push 
          message : "text"

I used 2 nested query to achieve that so firstly I get sender UID, and then I get the last message from another query

dataQuery = FirebaseDatabase.getInstance().getReference("Messages").child(my_Id);
    dataQuery.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot getalldata, String s) {

            final String sender_UID = getalldata.getKey();

            Query lastmess = FirebaseDatabase.getInstance().getReference("Messages").child(my_Id).child(sendUID);
            lastmess.orderByKey().limitToLast(1).addChildEventListener(new ChildEventListener() { // last message
                @Override
                public void onChildAdded(DataSnapshot snap, String s) {
                    MessModel messages = snap.getValue(MessModel.class);
                    String Last_message = messages.getMessage();
                    getUserData(Last_message ,sender_UID);

                }

                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) {

                }

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }
        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {


        }
        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

And finally I get information of sender by this method

private void getUserData(final String last_message , String sendUID) {
    FirebaseDatabase.getInstance().getReference("Users").orderByKey().equalTo(sendUID).addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(final DataSnapshot data, final String s) {

            listImessagesitem model = data.getValue(listImessagesitem.class);
            name =model.getName();
            uid = model.getUid();
            //another information

            result.add( new listImessagesitem( name ,last_message ,uid, ... another info));
            useradapter = new listMessagesAdapter(getActivity(),result);
            myList.setAdapter(useradapter);
            useradapter.notifyDataSetChanged();

        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }
        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {
        }

        @Override
        public void onCancelled(DatabaseError databaseError) { 
        }

    });
}

It works well the first time and when I make refresh as well

The problem is when someone, in the list of messages Inbox, sends me a new message. In this case, if I didn't make refresh, I see two senders with the same information and different last messages ... If he sent again, I see 3 senders with same previous case and so on.

How can I fix it?

I mean How can I add the new message to the user if he already exists in my inbox list

Any help would be appreciated, Thanks

Upvotes: 1

Views: 711

Answers (1)

vivek verma
vivek verma

Reputation: 1766

What I understand from looking at your code is that u have nested ChildEventListener's. So every-time the top listener is invoked a new inner child listener is created causing duplicate data as it calls the getUserData method to update the adapter.

What you can do?

1: Check if the result list contains the object if not then add otherwise ignore.

2: From what I understand, I believe you are trying to create a Mail Client application where two users are sending emails to each other. So instead of the structure that you have in your db why not create a single node for both the users something like this user_1_ID+user_2_ID .

This reduces the complexity as both the users will read from the same node and the message object should have a timestamp field to determine the latest message.

Upvotes: 1

Related Questions