FirebaseUI-Android
FirebaseUI-Android copied to clipboard
Manage cached image after uploading new image to Firebase Storage
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 ?
@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.
unique is the url of the image , try it i solved with that , i just puth url as signature , when geting imgage from
You can add a valueEventListener for the URL column , and every time it fires it should re-cache the image. Hope this helps
@hardik124 Would you mind elaborating on your suggestion? I am trying to solve the cache problem on iOS
@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.
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 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 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.
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");
}
});`
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
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 .
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 .
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.
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);
}
});
Hi @stasbar, did you find a solution for this?
This feature request is now tracked internally as b/160632091.
@yuchenshi Can you please elaborate or provide some link where I can look up.
@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.
facing same problem
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.