0

I am building a chatroom application and am trying to query all messages then separate them accordingly based on the message sender.

This is what my Firestore architecture looks like:

enter image description here

And my code so far:

 CollectionReference chatRoomMsgs = db.collection("chatrooms").document(chatRoomID).collection("Messages");
    chatRoomMsgs.get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                    for(QueryDocumentSnapshot documentSnapshot: queryDocumentSnapshots){
                        if(documentSnapshot.get("sentby") == firebaseUser.getUid()){

                        }
                    }
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {

                }
            });

What I am (currently) trying to do is pull ALL chatroom messages first, and then separate them out in onSuccess.

I am trying to say "ok if the message was sent by this user, grab the image field value of that same document and add it to an array so the image can be accessed later, and if the message was not sent by the same user, also grab the image url but add it to a different array"

How can I do this? Thanks!

Update I tried adding the while loop below to get some sort of output, wasn't triggering

ArrayList<String> sentPics = new ArrayList<String>();      
while(documentSnapshot.get("sentby") == firebaseUser.getUid()){
                                    sentPics.add(documentSnapshot.get("image").toString());
                                    Log.d("PICLIST", sentPics.toString());
                                }
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Ethan
  • 1,905
  • 2
  • 21
  • 50
  • 1
    Please only use the `android-studio` tag for questions about the Android Studio IDE itself. For questions about Android programming in general, use the `android` tag. – Frank van Puffelen Mar 22 '20 at 21:20

2 Answers2

1

If you want to get all the messages sent by a specific user, then you should use the following query:

CollectionReference chatRoomMsgs = db.collection("chatrooms").document(chatRoomID).collection("Messages");
Query sendByQuery = chatRoomMsgs.whereEqualTo("sentby", firebaseUser.getUid());
sendByQuery.addOnSuccessListener(/* ... */);

Using this solution you'll significantly reduce the number of read operations as you get as a result only the messages that correspond to the logged-in user.

Your solution is very expensive because you are getting all messages that exist in the Messages collection and you filter them on the client. If you have a total of 100 messages in the collection but only 10 correspond to the logged-in user, you'll be charged with 100 reads. In my solution, you'll only be charged with 10, as the query only 10 messages returns.

If want to see another approach, here you can find a tutorial on how to create a complete and functional Firestore Chat App.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Thanks for the suggestion, I have made that change, but the problem of then taking each of those image url's, retrieving them and pushing them into a custom gridview adapter still remains. – Ethan Mar 23 '20 at 14:36
  • That shouldn't be a problem. While iterating, you only need to get the image and add it to an array or a list. Having that list, then you can pass it to an adapter. If you have a hard time solving that, post another fresh question using its own [MCVE](https://stackoverflow.com/help/mcve), so I and other Firebase developers can help you. – Alex Mamo Mar 23 '20 at 15:26
  • Please see here: https://stackoverflow.com/questions/60819377/how-to-populate-a-gridview-with-images-retreieved-from-firebase-storage – Ethan Mar 23 '20 at 18:16
  • 1
    @Ethan I'll take a look and if I'll know the answer I'll write is to you. – Alex Mamo Mar 23 '20 at 19:13
0

What you need to do is make a POJO named Message that maps to your Messages collection with member variables image and sentby and convert the documentSnapshot to a Message object using:

Message message = documentSnapshot.toObject(Message.class)

From there on, you can just use the getters to achieve what you want.

Hope it helps!

Shahood ul Hassan
  • 745
  • 2
  • 9
  • 19