0

I have a CollectionView that I am using images from Firebase Storage to fill. I store the images under 'userId' node. I want to check the files existence in bulk that are available under the node, so I can store them in an array.

I tried to retrieve the urls separately for each one, however, I believe this is a very wrong approach. But, I couldn't figure out how to do it in most efficient way and where to put collectionView.reload(). This is what I did:

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

Also, is it better to fetch the image as NSData better than fetching the urls first and then fetching the images? If so, how can I retrieve images in bulk from Firebase Storage?

senty
  • 12,385
  • 28
  • 130
  • 260
  • 1
    from a team member http://stackoverflow.com/questions/37694009/how-to-download-and-view-images-from-the-new-firebase-storage/37694730#comment62885212_37694730 – Shubhank Jun 15 '16 at 16:36
  • Is there a way that I can get a completion of the three? What is the proper way of doing it? I'm confused about where to call `collectionView.reload()` if I do them separately. – senty Jun 15 '16 at 16:40
  • It sounds like you're hoping to load all files from a folder in one go. That is not a supported operation in Firebase Storage. I also doubt it would help much, since for most files the size of the file far outweighs the extra roundtrip required. – Frank van Puffelen Jun 15 '16 at 16:46

2 Answers2

2

Currently there's no bulk or batched upload/download to/from Firebase Storage--I think there are too many question here: would we zip the files up and store them that way, would we returned a zipped bundle, etc. Would we just return an array of download URLs, or appropriate data?

Our solution to the problem of listing and downloading multiple files is to upload them individually and store the URLs in another database (say the Firebase Realtime Database), which you can then sync and use to download each file individually (or you store the download files and use a tool like SDWebImage to download or cache the appropriate URLs).

See https://www.youtube.com/watch?v=xAsvwy1-oxE&feature=youtu.be for an example of how we did this.

Ashish
  • 6,791
  • 3
  • 26
  • 48
Mike McDonald
  • 15,609
  • 2
  • 46
  • 49
  • Sometimes, the url returned by `getDownloadUrl()` is not valid, so it is of no use to use Realtime database for this purpose. When you try to resume the upload using uploadSessionUri then the file is able to resume completely fine but the url returned by `onSuccess()` is not valid. However the file is completely fine in the console but url is not. What to do in that case? – CopsOnRoad Apr 01 '18 at 16:01
  • @CopsOnRoad the URL should always be valid (unless you've invalidated it in the console). If you've got a repro for us, please let support know (https://firebase.google.com/support/contact/bugs-features/) so we can see if there's a bug. – Mike McDonald Apr 02 '18 at 16:07
  • I didn't do anything from the console, in my logcat I saw `onSuccess()` got called and after that I logged the `getDownloadUrl()` from there. When I copied that link and pasted in the browser it didn't work. However when I did same steps with fresh uploading a file, it retuned a working url. So, I think there is a bug. I am going to submit a report on the link you wrote. Hoping to get some solution from your end. – CopsOnRoad Apr 02 '18 at 16:21
1

I don't know if this is what you want, but i figured out an easy way of uploading multiple files into the firebase storage and get their respective download urls.

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

        });

    }
zeenosaur
  • 888
  • 11
  • 16
Aman Chatterjee
  • 85
  • 1
  • 10