Как я могу получить URL изображений после того, как я загрузил их с циклом for в хранилище Firebase?

1

У меня есть массив файлов URI, и я загружаю их в хранилище Firebase с циклом for. Следуя документации, я могу получить URL-адрес загрузки, реализующий методы continueWithTask и addOnCompleteListener UploadTask объекта UploadTask, поэтому я пытаюсь сохранить все URL- UploadTask внутри массива. Моя проблема в том, что массив, который я использую для сохранения URL-адреса, пуст, но изображения загружаются в папку хранилища firestore после вычисления кода, вероятно, потому что continueWithTask и addOnCompleteListener являются асинхронными методами.

Как я могу решить это?

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);
                }
            }
        });    
}

Мой массив downloadUrl пуст по запросу URL

Теги:
firebase
google-cloud-firestore

1 ответ

1
Лучший ответ

Вы можете загрузить свои файлы один за другим и добавить Uri в список. Поскольку загрузка является асинхронной задачей, вам нужно обернуть весь блок в новый поток и дождаться завершения каждого из них, чтобы они выполнялись один за другим.

Когда я искал, есть существующие сообщения, спрашивающие, как ждать нескольких обратных вызовов. Я разместил ответ в одном из них. Вот ссылка на ответ. Читайте дальше после проверки.

Вот как это выглядит после реализации того, что там описано. (Я не запускал код. Могут быть незначительные ошибки.)

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();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню