0

I have reviewed other similar posts before posting this, mine is different I am current retrieving a list of download urls from my Firestore data base, then trying to download those images from my firebase storage to display them in a gridview.

This is my code so far:

final Query chatRoomMsgs = db.collection("chatrooms").document(chatRoomID).collection("Messages").whereEqualTo("sentby", firebaseAuth.getUid());
    chatRoomMsgs.get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                    ArrayList<String> sentPicsURLS = new ArrayList<String>();

                    for(QueryDocumentSnapshot documentSnapshot: queryDocumentSnapshots){

                        for(int i = 0; i < queryDocumentSnapshots.size(); i++) {
                            sentPicsURLS.add(documentSnapshot.get("image").toString());

                            if(i == (queryDocumentSnapshots.size()-1)){
                                //now download the images and place them into the proper view
                                for(int z = 0; z < sentPicsURLS.size(); z++){


                                }

                            }
                        }

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

                }
            });

This is where the images should be pulled and pushed into a gridview:

for(int z = 0; z < sentPicsURLS.size(); z++){
         //right here    
}

But I am having trouble creating an adapter that can handle this. I have a valid gridview in the activity and I have a layout file that contains an imageview with a ID.

final ArrayAdapter arrayAdapter = new ArrayAdapter(Chatroom.this, R.layout.chatroom_sent_images,R.id.sent_iv);
    sentPics.setAdapter(arrayAdapter);
    sentPics.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            //empty for now
        }
    });

The part I am missing (seems to be) where I actually loop through sentPicsURLS and then add them to the adapter... maybe with something like arrayAdapter.addAll(sentPicsURLS); inside the //right here for loop?

Right now the gridview is showing empty without even the default image view included in R.layout.chatroom_sent_images. I feel like I am so close, what am I missing? Thanks!

Edit Here is my chatroom database structure, every chatroom and chatroom message is structured the same way. enter image description here

Ethan
  • 1,905
  • 2
  • 21
  • 50
  • I amn't sure if i get you correct ,If i did so , You can use observer design pattern (create an interface , implement it in mainactivity , pass it to the adapter) and every time you successfully download an image pass it to the grid , And if you mean that you just want to pass the data , call setAdapter after the for loop – moumenShobakey Mar 23 '20 at 18:35
  • Do you have more than one image URL in a document? Please add your database schema as a screenshot. Please also respond with @AlexMamo – Alex Mamo Mar 24 '20 at 10:26
  • Just added @AlexMamo – Ethan Mar 24 '20 at 14:00

1 Answers1

1

As I see in your screenshot, your document hols only a single image. So to solve this, there is no need for an extra inner for-loop. To create a list of those images, please use the following lines of code:

Query chatRoomMsgs = db.collection("chatrooms").document(chatRoomID)
    .collection("Messages").whereEqualTo("sentby", firebaseAuth.getUid());
chatRoomMsgs.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            ArrayList<String> sentPicsURLS = new ArrayList<>();
            for (QueryDocumentSnapshot document : task.getResult()) {
                sentPicsURLS.add(document.getString("image"));
            }
            //Do what you need to do with your list
            Log.d(TAG, "List size: " + sentPicsURLS.size());
        }
    }
});

Be also aware that Firebase APIs are asynchronous and you can use that list only inside the callback. Now, the result in your logcat will be size of your list.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Ok @AlexMamo I have a ArrayList of all the images URLs... how can I pull them and populate a gridview? Assuming I need a custom arrayadapter, but it shouldn't be anything special, literally am looking for an instagram-like 3-wide gridview... so I created a layout with just one grid view in it, but I don't know how to actually get/download those images from my firebase storage...new question maybe? – Ethan Mar 24 '20 at 19:54
  • 1
    Good to hear that you made it work. Now that you have a list full of images, you just simply need to create an adapter and pass that list to a constructor. You should really make your own attempt given the information in this comment and if you have hard time implementing that, add a new question so we can see where you are stuck. – Alex Mamo Mar 24 '20 at 20:00
  • Please also note that your images are simply names` longId/number.jpg`. In order to get images from Firebase Storage, you need URLs. Those are not URLs. – Alex Mamo Mar 24 '20 at 20:02
  • will do... I was assuming I could just pass those half-URLs into some sort of constructor and add whatever precedes them programatically, then fetch the image and push it into the array adapter. No? – Ethan Mar 24 '20 at 20:08
  • 1
    Oh yes, you can construct the link on the client. It will work perfectly fine. – Alex Mamo Mar 24 '20 at 20:28
  • figured I could as the link to the should just be `firebaseappurl` + `sentPicsURLS.get(i)` – Ethan Mar 24 '20 at 20:33
  • 1
    Yes, that correct. You should only add the part with `https://...`. – Alex Mamo Mar 24 '20 at 20:35
  • do you know off hand what to call to download those images to the imageview? Do I need an external library like picasso or do they have a function built in like `download()` or something – Ethan Mar 24 '20 at 20:36
  • 1
    To get the download URL when you upload a picture check [this](https://stackoverflow.com/questions/53299915/how-to-get-offline-uploaded-file-download-url-in-firebase/53300660#53300660) out. And [Glide](https://stackoverflow.com/questions/58581858/how-to-avoid-downloading-image-from-firebase-if-i-have-already-downloaded-previo) will help you solve the other issue. – Alex Mamo Mar 24 '20 at 20:47
  • got it... I'm starting to wonder if 'download' the actually the right terminology because I don't want to download and permanently store the image onto the users device time and time again...they should only have/need to see the image when they are in the app – Ethan Mar 24 '20 at 20:56
  • 1
    Glide provides a cache so you are not going to download an image over and over again. – Alex Mamo Mar 24 '20 at 20:58
  • perfect, I'll read their documentation but I assume there's some sort of method I could call that would handle the removal of specific images from the grid view no – Ethan Mar 24 '20 at 21:17
  • have another for you... just cant wrap my mind around this https://stackoverflow.com/questions/60840789/how-to-load-and-add-images-to-an-android-arrayadapter-using-glide – Ethan Mar 24 '20 at 23:16