How to query unread messages num?

1.4k Views Asked by At

I'm developing a chat app which has many chat rooms, when someone replied to the chat room, he is automatically subscribed to it.

My Firebase database structure is:

chats
--chatID
----chatName
----user

unreadMessages
--chatID
----messageID
------userID

I tried to comment the code as much as possible for you so it would be easier to read.

Now, on my MainActivity I query to get all the chatrooms, and I want to get the unread messages number too. This requires multiple nested queries, and the problem is that they all occur in different times, therefore I can't know when the inner loops are finished and when the Firebase queries end.

It means that at the last line it adds the chatroom with 0 unread messages because of the timing.

Hope you could help me here, I tried almost anything, and hours of frustrating didn't help at all.

DatabaseReference chatsRef = database.getReference("chats");
    chatsRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {

            final String chatRoomID = dataSnapshot.getKey(); //get chatID


            //handle unread messages
            DatabaseReference unreadMessagesRef = database.getReference("unreadMessages").child(chatRoomID);
            unreadMessagesRef.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    Long totalMessagesNum = dataSnapshot.getChildrenCount(); //total messages in this chatroom

                    //get every message
                    for (DataSnapshot message : dataSnapshot.getChildren()) {

                        String messageID = message.getKey(); //get messageID
                        DatabaseReference singleMessageRef = database.getReference("unreadMessages").child(chatRoomID).child(messageID);
                        singleMessageRef.addValueEventListener(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                for (DataSnapshot user : dataSnapshot.getChildren()) {
                                    String userID = user.getValue(String.class);
                                    if( userID == currentLoggedUser.getID() ){
                                        //the user have read this message, substract from the total messages
                                        totalMessagesNum--;
                                    }
                                }
                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {

                            }
                        });

                    }
                }
                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });

            Log.i("total unread messages in this chat is " + totalMessagesNum);
            //add the chat to the listview
            chatsAdapter.add( new Chat(chatRoomID,totalMessagesNum) )

        }

        ...

    });
1

There are 1 best solutions below

0
On

You have multiple options. Two are below:

  1. You can store the unreadmessage count in firebase and query it directly.
  2. You can use callbacks so that when you get the result back from your first query you call the callback and then perform the second query. Once the second query returns you can add the final values to your chatsAdapter.