FirebaseUI-Android icon indicating copy to clipboard operation
FirebaseUI-Android copied to clipboard

Manage cached image after uploading new image to Firebase Storage

Open stanbar opened this issue 7 years ago • 20 comments

Hello. I'm using FirebaseUI-Storage to load user avatar, it's working great but there is a problem when user change avatar (upload new image to Firebase Storage) and it does not change with next Glide request (it load deprecated image from cache). I don't want to disable Glide Cache Policy. I think it should work like this:

StorageReference avatarRef = ...
Glide.with(this)
                    .using(new FirebaseImageLoader())
                    .load(avatarRef)
                    .signature(new StringSignature(avatarRef.lastModified()))
                    .into(ivUserAvatar);

But there is no way to get any unique information about this image to set signature. Do you have any ideas ?

stanbar avatar Dec 28 '16 23:12 stanbar

@stasbar sorry for the late response. I saw this and responded in my head but I couldn't think of an answer.

I don't have any answer but I will ask around.

samtstern avatar Jan 09 '17 23:01 samtstern

unique is the url of the image , try it i solved with that , i just puth url as signature , when geting imgage from

champrocks3190 avatar Jan 13 '17 15:01 champrocks3190

You can add a valueEventListener for the URL column , and every time it fires it should re-cache the image. Hope this helps

hardik124 avatar Jan 13 '17 21:01 hardik124

@hardik124 Would you mind elaborating on your suggestion? I am trying to solve the cache problem on iOS

haansplosion avatar Jan 16 '17 12:01 haansplosion

@haansplosion You can store the images in any storage and store the link in firebase database , and every time user uploads a new image , the URL will change and since FIRDataEventTypeValue method is triggered once when the listener is attached and again every time the data, including any children, changes. and everytime it fires , just clear the cached image in local memory and cache the new one.

hardik124 avatar Jan 16 '17 14:01 hardik124

I agree with @hardik124, the best thing to do (if it works for your application) is to not overwrite images at a particular storage location but rather upload all images to unique URLs and just change your stored reference to the URL.

samtstern avatar Jan 17 '17 16:01 samtstern

@samtstern the workaround mentioned by @hardik124 will do the job, but is there anyway using firebase-Storage to resolve this without any dependency of firebasedatabase here. Like do we have an option of the type of "valueEventListener" or similar for storage data?

mailtoabhi15 avatar Jun 07 '17 09:06 mailtoabhi15

@mailtoabhi15 if you want to 'listen' to data in Storage you could use a Cloud Function that will run every time an object is changed. But there is no way to do it with the client SDK alone.

samtstern avatar Jun 07 '17 14:06 samtstern

If you can live with "seeing default placeholder images always first" then go for this..


Utility.getProfileImageFromUser(userID).getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
            @Override
            public void onSuccess(StorageMetadata storageMetadata) {
                GlideApp.with(parentActivity)
                        .load(Utility.getProfileImageFromUser(userID))
                        .signature(new MediaStoreSignature("", storageMetadata.getCreationTimeMillis(), 0))
                        .into(imgPb);
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.d(TAG, "getProfilePicture -> no picture found");
            }
        });`

n1xn avatar Dec 14 '17 05:12 n1xn

I got the same problem and I can't use url since I have some gs://child/default and they can be uploaded directly to the storage from the client.

I found a solution handling in 2 different ways: When a pic is uploaded by the app I save the path in Firestore appending a $ and a random number to the string, then:

  • if path contains $ use the path as key a the path trimmed before $ for load data
  • if path doesnt contain $ (for instance 'storage://news/default.jpeg' ) append a number representing the a time range to the path: example (I will use conventional number for time for clarity, but in the app I will use time in milliseconds) path is storage://news/default.jpeg, now is 2018/02/23 23.54, so the key will be storage://news/default.jpeg2018022323 and I will know its will be valid just for this hour, or maybe storage://news/default.jpeg20180223 for let it being valid for entire day.

Also I set a JobService cleaning the Glide cache every 3 weeks for i won't usa 200MB for cache.

This solution is good, but I would like to use Firebase function and clean cache for a single key, is it possible? It would allow me to clean cache every 3 months maybe and avoid to load those default pictures every hour

ghost avatar Feb 24 '18 22:02 ghost

i hope firebase can implement some method that can be directly call like

storage.lastmodified or something that can be use as signature without calling it in onsuccess metadata or any other timestamp bcoz if having 500 list of data having offline access of user list say it decreases performance too much . as sending request in on bind method of rcv to set metadata as signature.

any one have good solution pls let know. without doing any network calls .

champrocks3190 avatar Apr 26 '19 18:04 champrocks3190

Hello. I'm using FirebaseUI-Storage to load user avatar, it's working great but there is a problem when user change avatar (upload new image to Firebase Storage) and it does not change with next Glide request (it load deprecated image from cache). I don't want to disable Glide Cache Policy. I think it should work like this:

StorageReference avatarRef = ...
Glide.with(this)
                    .using(new FirebaseImageLoader())
                    .load(avatarRef)
                    .signature(new StringSignature(avatarRef.lastModified()))
                    .into(ivUserAvatar);

But there is no way to get any unique information about this image to set signature. Do you have any ideas ?

im also in to the same situation today .

champrocks3190 avatar Apr 26 '19 19:04 champrocks3190

No updates on this? It was opened more than 2 years ago. I am running into the same issue. I want users to only have one avatar so creating new URLs for each upload and deleting the old one seems like a bad workaround.

nak411 avatar May 16 '19 01:05 nak411

If you can live with "seeing default placeholder images always first" then go for this..

Utility.getProfileImageFromUser(userID).getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
            @Override
            public void onSuccess(StorageMetadata storageMetadata) {
                GlideApp.with(parentActivity)
                        .load(Utility.getProfileImageFromUser(userID))
                        .signature(new MediaStoreSignature("", storageMetadata.getCreationTimeMillis(), 0))
                        .into(imgPb);
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.d(TAG, "getProfilePicture -> no picture found");
            }
        });`

The URL will be updated each time a new image is uploaded. So, Instead of getMetadata, getDownloadUrl should also work without any signature.

storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
        @Override
        public void onSuccess(Uri uri) {
            Glide.with(context)
                .load(uri)
                .into(imageView);
        }
    });

safu9 avatar May 23 '20 16:05 safu9

Hi @stasbar, did you find a solution for this?

KomalChugh avatar Jun 29 '20 13:06 KomalChugh

This feature request is now tracked internally as b/160632091.

yuchenshi avatar Jul 06 '20 21:07 yuchenshi

@yuchenshi Can you please elaborate or provide some link where I can look up.

KomalChugh avatar Jul 07 '20 06:07 KomalChugh

@KomalChugh sorry we're just doing some housekeeping to keep track of GitHub issues. @yuchenshi made an entry in our internal bug tracker representing this issue. There's nothing new you can look up and if we do decide to implement this feature we will update you here.

samtstern avatar Jul 07 '20 12:07 samtstern

facing same problem

visvajeet avatar Jun 05 '21 20:06 visvajeet

I think the Firebase team can easily fix it. Since this lib downloads the image from firebase storage they can verify the cache also. why the cache is not verified? I can not switch to URLs since I am storing user profile picture ref in different documents and collection.

visvajeet avatar Jun 05 '21 20:06 visvajeet