Получить несколько фотографий под узлом из хранилища Firebase

У меня есть CollectionView, для заполнения которого я использую изображения из хранилища Firebase. Я храню изображения в узле «userId». Я хочу проверить наличие файлов в большом количестве, доступных под узлом, чтобы я мог хранить их в массиве.

Я попытался получить URL-адреса отдельно для каждого, однако я считаю, что это очень неправильный подход. Но я не мог понять, как это сделать наиболее эффективно и куда поставить collectionView.reload(). Вот что я сделал:

let storage = FIRStorage.storage()
let firstImageRef = storage.referenceForURL("gs:storageUrl").child(uid).child("profile.jpg")

firstImageRef.downloadURLWithCompletion { (URL, error) -> Void in
   if (error != nil) {
       print(error)
   } else {
       if let url = URL {
         self.databaseImagesOrder.append(url)
       }
   }
}

let secondImageRef = storage.referenceForURL("gs:storageUrl").child(uid).child("second_pic.jpg")
secondImageRef.downloadURLWithCompletion { (URL, error) -> Void in
   if (error != nil) {
      print(error)
   } else {
      if let url = URL {
        self.databaseImagesOrder.append(url)
      }
   }
 }

 // etc.. 

 collectionView.reloadData()

Кроме того, лучше ли извлекать изображение как NSData лучше, чем сначала извлекать URL-адреса, а затем извлекать изображения? Если да, то как я могу массово получать изображения из хранилища Firebase?


person senty    schedule 15.06.2016    source источник
comment
от члена команды stackoverflow.com/questions/37694009/   -  person Shubhank    schedule 15.06.2016
comment
Есть ли способ, которым я могу получить завершение трех? Каков правильный способ сделать это? Я не понимаю, куда звонить collectionView.reload(), если я делаю их отдельно.   -  person senty    schedule 15.06.2016
comment
Похоже, вы надеетесь загрузить все файлы из папки за один раз. Это не поддерживается в Firebase Storage. Я также сомневаюсь, что это сильно поможет, поскольку для большинства файлов размер файла намного превышает требуемый дополнительный цикл.   -  person Frank van Puffelen    schedule 15.06.2016


Ответы (2)


В настоящее время нет массовой или пакетной загрузки/выгрузки в/из Firebase Storage — я думаю, что здесь слишком много вопросов: будем ли мы заархивировать файлы и хранить их таким образом, будем ли мы возвращать заархивированный пакет и т. д. Мы просто вернем массив URL-адресов загрузки или соответствующие данные?

Наше решение проблемы перечисления и загрузки нескольких файлов состоит в том, чтобы загрузить их по отдельности и сохранить URL-адреса в другой базе данных (скажем, в базе данных реального времени Firebase), которую затем можно синхронизировать и использовать для загрузки каждого файла по отдельности (или вы сохраняете загружаемые файлы и используйте такой инструмент, как SDWebImage, чтобы загрузить или кэшировать соответствующие URL-адреса).

См. https://www.youtube.com/watch?v=xAsvwy1-oxE&feature=youtu.be для примера того, как мы это сделали.

person Mike McDonald    schedule 16.06.2016
comment
Иногда URL-адрес, возвращаемый getDownloadUrl(), недействителен, поэтому для этой цели бесполезно использовать базу данных реального времени. Когда вы пытаетесь возобновить загрузку с помощью uploadSessionUri, файл может возобновиться полностью нормально, но URL-адрес, возвращаемый onSuccess(), недействителен. Однако с файлом в консоли все в порядке, а с URL-адресом - нет. Что делать в таком случае? - person CopsOnRoad; 01.04.2018
comment
@CopsOnRoad URL-адрес всегда должен быть действительным (если только вы не сделали его недействительным в консоли). Если у вас есть копия для нас, сообщите об этом в службу поддержки (firebase.google. com/support/contact/bugs-features), чтобы мы могли увидеть, есть ли ошибка. - person Mike McDonald; 02.04.2018
comment
Я ничего не делал из консоли, в своем логарифме я увидел, что onSuccess() вызвали, и после этого я зарегистрировал getDownloadUrl() оттуда. Когда я скопировал эту ссылку и вставил в браузер, она не работала. Однако, когда я сделал те же шаги с новой загрузкой файла, он перенастроил рабочий URL-адрес. Итак, я думаю, что это ошибка. Я собираюсь представить отчет по ссылке, которую вы написали. Надеясь получить какое-то решение с вашей стороны. - person CopsOnRoad; 02.04.2018

Я не знаю, хотите ли вы этого, но я нашел простой способ загрузки нескольких файлов в хранилище Firebase и получения соответствующих URL-адресов для загрузки.

  private void uploadPosts(final ArrayList<String> mediaUris) {

        StorageReference fileRef = storageRef.child("users").child(Objects.requireNonNull(mAuth.getCurrentUser()).getUid()).child("posts").child(key).child("file_" + index);
        File mediaFile = new File(mediaUris.get(index));


        final UploadTask uploadTask = fileRef.putFile(Uri.fromFile(mediaFile));
        uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(final UploadTask.TaskSnapshot taskSnapshot) {
                fileRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {

                        Log.d(TAG,"URL = "+uri); //url of each file

                        if(index < mediaUris.size()) {
                            index++;
                            uploadPosts(mediaUris); //Recursion
                        }

                    }
                });
            }

        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(getApplicationContext(), "Upload failed", Toast.LENGTH_SHORT).show();
                Log.e(TAG,"Failed "+e.getCause());
            }

        });

    }
person Aman Chatterjee    schedule 16.01.2019