Images on Firebase Storage with Firebase-UI RecyclerView

4,223 views
Skip to first unread message

Janaka Jayasuriya

unread,
Jun 1, 2016, 10:58:19 AM6/1/16
to Firebase Google Group
Hello,

Just wondering what the best practice is when you want to load images stored on Firebase Storage in your app in a Firebase-UI ListView or RecyclerView. Is there some built in mechanism in Firebase-UI, or should you get the image's url and use Glide, or some other method?

If I am to use Glide and urls, is it advisable to store the url in the Firebase Databse child node where the rest of the recycler view item data is at? Images should be available to any user on the app (even anonymous users), but should not be publicly accessible.

Best,
Janaka J.


Samuel Stern

unread,
Jun 1, 2016, 2:24:44 PM6/1/16
to Firebase Google Group
I think you have the right idea here.  Storing the URL (that you get from the Storage Metadata) in Firebase Database is a great way to have it ready to load via Glide when you are populating your RecyclerView.  It's a technique I have used before and it works well.  If you also store some basic information about the image (such as the size) you can pre-size the ImageView while Glide loads the image, which will make your UI less jumpy.

Regarding access controls, the URLs generated by FirebaseStorage are publicly accessible so if you store them in FIrebase Database you should make sure you have the appropriate security rules on those paths.  If that's something you're worried about, you could do the following:

  1. Upload the image to a StorageReference
  2. Store the StorageReference path value (getPath()) in the Database, rather than the actual URL to the image data (which is publicly accessible)
  3. When populating the RecyclerView, use that path to get a new StorageReference and download the image using Glide (see below)
For Glide specifically, I have found a very nice way to load an image from a StorageReference by creating a custom ModelLoader.  Here's the code (from one of my own projects);

/**
 * ModelLoader implementation to download images from FirebaseStorage with Glide.
 *
 * Sample Usage:
 * <pre>
 *     StorageReference ref = FirebaseStorage.getInstance().getReference().child("myimage");
 *     ImageView iv = (ImageView) findViewById(R.id.my_image_view);
 *
 *     Glide.with(this)
 *         .using(new FirebaseImageLoader())
 *         .load(ref)
 *         .into(iv);
 * </pre>
 */
public class FirebaseImageLoader implements StreamModelLoader<StorageReference> {

    @Override
    public DataFetcher<InputStream> getResourceFetcher(StorageReference model, int width, int height) {
        return new FirebaseStorageFetcher(model);
    }

    private class FirebaseStorageFetcher implements DataFetcher<InputStream> {

        private StorageReference mRef;

        FirebaseStorageFetcher(StorageReference ref) {
            mRef = ref;
        }

        @Override
        public InputStream loadData(Priority priority) throws Exception {
            return Tasks.await(mRef.getStream()).getStream();
        }

        @Override
        public void cleanup() {
            // No cleanup possible, Task does not expose cancellation
        }

        @Override
        public String getId() {
            return mRef.getPath();
        }

        @Override
        public void cancel() {
            // No cancellation possible, Task does not expose cancellation
        }
    }
}

Good luck!

- Sam

Janaka Jayasuriya

unread,
Jun 2, 2016, 10:35:04 AM6/2/16
to Firebase Google Group
Hi Sam,

Thanks for sharing this bit of code, it works perfectly! Also nice tip about storing the size and pre-sizing the image views.

Best,
Janaka J.

Samuel Stern

unread,
Sep 26, 2016, 12:37:58 PM9/26/16
to Firebase Google Group
Just to follow up on this thread (in case anyone comes across it), we packaged this snippet (with some improvements) into the FirebaseUI-Android library version 0.6.0:

More firebase-ui-storage features coming soon, this is just the beginning!

- Sam
Reply all
Reply to author
Forward
0 new messages