Cache images local, from google firebase storage

2020-01-28 08:33发布

问题:

I am searching for a way, to cache images from the storage on google firebase platform. For now, I can download images, and show these to users, but I am not able to cache this, and access, even without internet connection. The database can be accessed offline. So I thought, there would be a way for storage too. I don't want to download every single image to storage, cause then I would need to check everytime, if the image is still up to date, it may be changed. Here are few links, what I could find, but no answer for my question. Maybe someone know a workaround, or a way how to accomplish it. Thanks!

Download files: https://firebase.google.com/docs/storage/android/download-files

Cache (offline) database: https://firebase.google.com/docs/database/android/offline-capabilities

UPDATE 1

Here is how I "cache" files with picasso, I added activity, that cares the download:

Picasso.with(getApplicationContext())
                            .load(uri.toString())
                            .networkPolicy(NetworkPolicy.OFFLINE)
                            .into(image1);

Any help is welcome. Thanks!

回答1:

I'm afraid the Firebase SDK doesn't provide image caching by itself. But there are several great libraries that could do it for you. They download image, show it in an ImageView and cache it in a single line of code. Just request the Firebase for an image download url and feed it to the image caching library.

Something like this, if you choose Picasso as a caching library:

storageRef.child("users/me/profile.png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
    @Override
    public void onSuccess(Uri uri) {
        // Got the download URL for 'users/me/profile.png'
        // Pass it to Picasso to download, show in ImageView and caching
        Picasso.with(context).load(uri.toString()).into(imageView);
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
});

UPD: To use disk caching with Picasso you need to explicitly setup OkHttpDownloader. Look here How do I use disk caching in Picasso?



回答2:

Thanks to @ATom for notice. Api has changed, and FirebaseUI 3.0 now uses Glide 4.x Here is updated sample:

To load an image from a StorageReference, first register in your AppGlideModule:

@GlideModule
public class MyAppGlideModule extends AppGlideModule {

    @Override
    public void registerComponents(Context context, Glide glide, Registry registry) {
        // Register FirebaseImageLoader to handle StorageReference
        registry.append(StorageReference.class, InputStream.class,
                new FirebaseImageLoader.Factory());
    }
}

Then you can load a StorageReference into an ImageView:

// Reference to an image file in Cloud Storage
StorageReference storageReference = ...;

// ImageView in your Activity
ImageView imageView = ...;

// Download directly from StorageReference using Glide
// (See MyAppGlideModule for Loader registration)
GlideApp.with(this /* context */)
        .load(storageReference)
        .into(imageView);

And don't forget to add dependency in your build.gradle:

implementation 'com.firebaseui:firebase-ui-:3.1.0'

Answer source on GitHub

Old answer:

FirebaseUI 1.0 now released. Storage example has class FirebaseImageLoader

Images displayed using FirebaseImageLoader are cached by their path in Firebase Storage, so repeated loads will be fast and conserve bandwidth.

    // Reference to an image file in Firebase Storage
    StorageReference storageReference = ...;

    // ImageView in your Activity
    ImageView imageView = ...;

    // Load the image using Glide
    Glide.with(this /* context */)
            .using(new FirebaseImageLoader())
            .load(storageReference)
            .into(imageView);


回答3:

I had the same issue. Tried all possible ways but couldn't fix that. I think the problem lies with the links generated by firebase storage. Picasso generally caches the images it loads. I have tried other cloud services like cloudinary, LibPixel whose links end with image format (Eg:.jpg) and picasso caches these link images. While firebase links end with token numbers. Strange thing it fails!