0
votes

I couldn't find resources discussing the difference between the three download methods in the firebase storage documentation and pros/cons of each. I would like some clarification about the firebase storage documentation.

My App

  • Displays 100 images ranging from 10 KB-500 KB in size on a table view
  • Will be used in a location where internet connection and/or phone service could be very weak
  • Could be used by many users

3 methods for downloading from Firebase storage

  1. Download to NSData in memory

    This is the easiest way to quickly download a file, but it must load entire contents of your file into memory. If you request a file larger than your app's available memory, your app will crash. To protect against memory issues, make sure to set the max size to something you know your app can handle, or use another download method.

Question: I tried this method to display 100 images that were 10KB-500KB in size on my table view cells. Although my app didn't crash, as I scrolled through my table, my memory usage increased to 268 mb. Would this method not be recommended for displaying a lot of images?

  1. Download to an NSURL representing a file on device

    The writeToFile:completion: method downloads a file directly to a local device. Use this if your users want to have access to the file while offline or to share in a different app.

Question: Does that mean all images from firebase storage will be downloaded on user's phone? Does that mean that the app will be taking up a large percentage of the available storage on the phone?

  1. Generate an NSURL representing the file online

If you already have download infrastructure based around URLs, or just want a URL to share, you can get the download URL for a file by calling the downloadURLWithCompletion: method on a storage reference.

Question: Does this method require a strong internet connection and/or phone service connection to work?

1

1 Answers

2
votes

Generally, your memory usage should not be affected by the method of retrieval. As long as you're displaying the 100 images, their data will be stored in the memory and should have the same size if they're identically formatted/compressed.

Either way you go with, I suggest you implement pagination (for your convenience, this question's answer might serve as a good implementation reference/guide) to possibly decrease the memory and network usage.

Now, down to comparing the methods:

  • Method 1

    ...but it must load entire contents of your file into memory.

    This line might throw some people off thinking it's a memory-inefficient solution, when all it really means is that you cannot retrieve parts of the data, you can only download the entire file. In the case of storing images, you probably would want that for the data to make sense.

    If your application needs to download the images every time the users access it (i.e if your images are regularly updated), then this method will probably suit you best. The images will be downloaded every time the application starts, then they'll get discarded when you kill it.

    You stated that a part of your user base might have a weak internet connection and so the next method might be more efficient and user-friendly

  • Method 2

    First off, the answers to your questions:

    1. Yes. The images downloaded using this method will be stored on the users' devices.
    2. The images should take up about the same size they're taking on Firebase storage.

    Secondly, if you plan to use this method, then I suggest you store a timestamp (or any sort of marker) in your database for when the last change to the images occurred. Then, every time the app opens up, do the following flow:

    1. If no images are downloaded -> download images and store the database timestamp locally
    2. If the local timestamp does not equal the timestamp on the database -> download images and store the new timestamp locally
    3. Else -> use the images you already have, they should be identical to the ones in Firebase storage

    That would be the best way to go if your network usage priority is higher than that of the local storage.

    And finally...

  • Method 3 (not really)

    This is not a data download method, this simply generates a download URL given a reference to the child. You can then use that URL to download the data in your app or elsewhere as long as the used app or API is authorized to access your Firebase storage.

    Update:

    The URL is generated from a Firebase reference (FIRDatabase.database().reference().child("exampleReference")) and would look like this: (Note: this is a fake link that will not actually work, just used for illustration purpose)

    https://firebasestorage.googleapis.com/v0/b/projectName.appspot.com/o/somePathHere%2FchildName%2FsomeOtherChildName%2FimageName.jpg?alt=media&token=1a8f83a7-95xf-4d3s-nf9b-99a274927bcb
    

    If you simply try to access that link you generate through any regular web-browser (assuming you don't have any Firebase rule that conflicts with that in your project), you can directly download that image from anywhere, not just through your app.

    So in conclusion, this "Method" does not download data from Firebase storage, it just returns a download URL for your data in case you want a direct link.