I'm using Glide and Firebase for loading and cashing images. Usually, I use Signature with image created time then determine cache time. But in Firebase I can get created time only using second request getMetadata(). How do I make caching correctly when i change one image to another with same name in my storage? Should I use getMetadata() or there are other ways?
Glide.with(getContext())
.using(new FirebaseImageLoader())
.load(storageReference.child(item.getImageUrl()))
.placeholder(R.drawable.category_image_not_found)
.signature(???)
.into(image);
I was stuck in a similar situation for as long as I can remember! Using getMetadata() is slow, and causes delays. What I figured was that to keep my image up to date, there was no other option but to incorporate the Realtime Database. This can be done in one of the following ways :-
First :
Whenever the image at the particular storage location is edited, you update the timestamp for that image's node in your realtime database. And when you want to display the image, just download its timestamp and write a Glide.signature(timestamp) method similar to what you mentioned.
Second :
Just obtain the download URL of the image whenever you upload/edit it, and save the URL in the realtime database. In this way, whenever the image is updated, a different URL is saved to the same location. This guarantees that your cache does not show outdated images (changing URL of source is the advocated method to invalidate caches for Glide).
I understand that there could be overhead involved with retrieving data from the realtime database first and then downloading the image. However, that's the only way to go when using Glide + Firebase. Plus, enabling persistence and other realtime database quirks can make it seamlessly fast!
Related
About Single Sources of Truth Google document said:
Using this model, the database serves as the single source of truth, and other parts of the app access it using our UserRepository. Regardless of whether you use a disk cache, we recommend that your repository designate a data source as the single source of truth for the rest of your app
https://developer.android.com/jetpack/guide?gclid=CjwKCAjwo4mIBhBsEiwAKgzXOH1Pq--Ws1PLzUiSP4RmDE6ByKfEi6mdXu5g86btqveIdJvvrgYuxBoCz8wQAvD_BwE&gclsrc=aw.ds#connect-viewmodel-repository
According to the document I save all data when I fected data from remote server and I only get data from room When I need to use in acitivty(In fact I collect flow which is defined in viewmodel).
It seems so good! It avoids the different data sources mix up together! But actually I found some strange question gradually:
In my App, I have a list that the server may change it(Because we have data manager website that admin can update or delete data). So in order to get the newest list data from server, I must clear all data stored in room and fect data again from remote server. This operation seems redundant: "why could I get data directly from remote server", I mean, I only get data from remote source is also a single sources truth. And also it cause a promble: my app will flash a moment because clear data make list empty and fect data from server make list full!
The most important thing is that it seems like the local data is not necessary because I must stay the newest list from remote server.
Some people may say that save data into room can make us app available offlice. I agree that, But in this place, my item of list is represent a image url, and after click the item, the app will jump to a new activity and display a ImageView base on the url we get from the list. If app offlice, the ImageView couldn't load the url also.
I am so confused I couldn't load all image url(use base64-url to avoid load invalid) in a moment also, because the data is so much. And if I say I need a search function in this list and I need load so much unbelievable data into my room, It seems so unreal and event fantasy!
In brief:
Room is a nessary? Couldnt just fect data from remote?
If room is nessary, how to solve problem I met, do my incorrect useage cause the problem?
Hi #psycongroo as I Understood your problem, and I want to share my experience:
You can handle any error with loading URL with placeholder I mean if you got an error with no Internet connection user will see placeholder, but in general libs like Picasso or Glide can cache images when it`s load one time, so the user will see the Image.
The question about why we need to use room instead of fetch data from remote directly. So from your question I don`t understand why you need to drop your local changes even they are completely new, user can have a low internet connection so he will see an empty list instead of previous data with for example progress indicator. And also if the user doesn't have the internet at all you can show some dialog to explain what the problem but old data is still present. If you are using, for example, RecyclerView you can update data with Paging 3 from google, and they update the only necessary items from your list.
P.S. let me know if that help, or you have another question.
I am really confused about the process of retrieving and displaying images to your android app from firebase cloud storage. I looked around the web, but am unable to get a definitive answer to my questions.
With regards to my app, I simply want a place to store a bunch of images (around 2500) that I can display. I don't use authentication and I don't mind making these images public.
Do I have to request a download URL every time I want to retrieve an image from storage? I am worried because Firebase Storage allows you to download 1GB/day and only 50k/day download operations for free, which is not a lot of download operations for 2500 images.
Is there a way for me to access and display images without having to call reference.getDownloadUrl() ** every time I display an image?** Maybe some sort of workaround by making the images public and then storing the cloud storage URLs in a Room Database?
Any help is appreciated.
Do I have to request a download URL every time I want to retrieve an image from storage?
No, you can use the same URL repeatedly. Store that URL anywhere you like. But you will always pay the cost for egress every time the URL is accessed. There are no free downloads after the free allowance.
Is there a way for me to access and display images without having to call reference.getDownloadUrl() every time I display an image?
No, as I said above, you can reuse the same URL if you want. You can also configre the entire cloud storage bucket as public and simply build URLs to object as described in the links here. But again, downloads will be billed according to the normal Cloud Storage rates.
Please enable Firebase Storage for your bucket by visiting the Storage tab in the Firebase Console and ensure that you have sufficient permission to properly provision resources.",
"status": "ACCESS_BUCKET"
I am trying to store image from firebase database and named it FirebaseuniqUserID.jpeg.(like buwkgefuikbuifbkc8gfybfy.jpeg). And user can change image anytime.
For getting image link from firebase realtime database i used addListenerForSingleValueEvent.
FirebaseDatabase.getInstance().getReference().child("Users").child(FirebaseuniqUserID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//here i am downloading image//
//and named it FirebaseuniqUserID.jpeg
}
Now the problem is this when this listener is called every time image is download.
But now i want avoid downloading if current user has latest updated image of user in firebase to reduce firebase downloaded data.
I want avoid downloading if current user has latest updated image of user in Firebase
To solve this, I definitely recommend you to use an image loading and caching library. For Android we have Glide:
Glide is a fast and efficient open source media management and image loading framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface.
You can use two different options, first is Glide and 2nd is that, you can save image downloading status in your local database file or SharePreferences. But image cache is the best solution.
Hi guys I am making a wallpaper android app.I have stored all my images in firebase storage. Now I have a recyclerview and want to retrieve each of the images into that recyclerView by getting list url of the folders.Is there any way to do that without using the database.I have pasted the json file into my app.
In order to download a image/images from Firebase Storage, you first need to have the corresponding url/urls. To download an image, it requires four steps:
Upload the image to Firebase Storage.
Save the corresponding URL to Cloud Firestore/Firebase Database database while uploading.
Attach a listener on the folder you have saved the image.
Display the image.
So there is no way in which you can download an image without knowing the URL. You cannot get the image list URL directly from Firebase Storage.
First at all you need to have corresponding URLs of your image data stored in Firebase, as mention Alex Mamo. You can build list of this urls during upload or copy them from Firebase Console. Storage API doesn't provide any way how to retreive list of stored files.
Also, you can find Download URL in Image detail/properties. Then you can insert urls into JSON file (or another file, service, firebase storage, whatever) and load them in app.
But be careful, this is not a good idea because Firebase Storage (especially spark plan has limits) allow you download 1GB/day and only 50k/day (download/upload) operations. That will be wasted pretty soon if you don't optimise your data and number of reading operations.
Tip: When you select pay as you go most expensive is GB Downloaded, so you absolutely should store at least 1 thumbnail which will be shown in your recycler view.
In my application when i query a http URL i get list of object, some times these object needs to be rendered on listview and sometimes in my custom view.
Each of the object which i receive from server has image tag, most of the time images are always constant i.e same image URL only.
I just want to download the images once, & also my app should have to download once in a while when the images got changed in server. What is the best way?
I know like, we need to perform operation in thread, but not getting the exact idea of how to do?. how to check for change of image & efficient way of storing them. Any hint
For storage, I recommend Internal Storage
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
And for downloading
http://developer.android.com/reference/android/os/AsyncTask.html
You can create a AsyncTask where you pass a ImageView, where you want to show the img, with the url as a tag. And check in the internal storage if you have that img already saved if not just download it.