Luca94
Luca94

Reputation: 25

How can i get the url of the images after i've uploaded them with a for loop on firebase storage?

I have an array on URI files and i upload them on firebase storage with a for loop. Following the documentation, i can get the download url implementing continueWithTask and addOnCompleteListener methods on UploadTask object, so i try to save all the url inside an array. My problem is that the array that i use to save the url is empty but the images are uploaded on firestore Storage folder after the computation of the code probably because continueWithTask and addOnCompleteListener are asynchronous methods.

How can i solve it?

for (int i = 0; i < photos.size(); i++) {   
 mStorage=FirebaseStorage.getInstance().getReference().child("images/" + j);
mUploadTask=mStorage.putFile(photos.get(i));

Task<Uri>urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
            @Override
            public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
                if(!task.isSuccessful()){
                   throw task.getException();
               }
               return mStorage.getDownloadUrl();
            }
        }).addOnCompleteListener(new OnCompleteListener<Uri>() {
            @Override
            public void onComplete(@NonNull Task<Uri> task) {
               if(task.isSuccessful()){
                    String url = task.getResult().toString();
                    downloadUrl.add(url);
                }
            }
        });    
}

My array downloadUrl is empty after the request of the url

Upvotes: 1

Views: 239

Answers (1)

Bertram Gilfoyle
Bertram Gilfoyle

Reputation: 10235

You can upload your files one by one and add the Uris to a list. Since the upload is an asynchronous task, you have to wrap the entire block into a new thread and wait for each one to complete making them execute one by one.

When I searched, there are existing posts asking how to wait for multiple callbacks. I posted an answer in one them. Here is the link to the answer. Read further after checking it.

Here how it looks like after implementing what is described there. (I haven't run the code. There may be minor mistakes.)

new Thread(new Runnable() {
    @Override
    public void run() {
        final List < String > urls = new ArrayList();

        for (int i = 0; i < photos.size(); i++) {
            mStorage = FirebaseStorage.getInstance().getReference().child("images/" + j);
            mUploadTask = mStorage.putFile(photos.get(i));

            final ThreadLockedTask < String > t = new ThreadLockedTask < > ();
            final String url = t.execute(new Runnable() {
                @Override
                public void run() {
                    Task < Uri > urlTask = uploadTask.continueWithTask(new Continuation < UploadTask.TaskSnapshot, Task < Uri >> () {
                        @Override
                        public Task < Uri > then(@NonNull Task < UploadTask.TaskSnapshot > task) throws Exception {
                            if (!task.isSuccessful()) {
                                t.setResult(null);
                                throw task.getException();
                            }
                            return mStorage.getDownloadUrl();
                        }
                    }).addOnCompleteListener(new OnCompleteListener < Uri > () {
                        @Override
                        public void onComplete(@NonNull Task < Uri > task) {
                            if (task.isSuccessful()) {
                                String url = task.getResult().toString();
                                t.setResult(url);
                            }
                        }
                    });


                }
            });
            if(url!=null)
                urls.add(url);
        }

        //Now you have all the urls in the list "urls"
    }
}).start();

Upvotes: 1

Related Questions