I have a PWA running on Firebase. My image files are hosted on the Firebase Storage. I've noticed my browser doesn't save cache for files loaded from the storage system. The browser requests the files for every page refresh. It causes unnecessary delay and traffic.
My JS script loads the files from the Firebase Storage's download link, example: https://firebasestorage.googleapis.com/v0/b/discipulado-7b14b.appspot.com/o/book3.png?alt=media&token=65b2cde7-c8a4-45da-a743-401759663c17.
Can I cache those requests?
UPDATE
According to these answer I shouldn't use Firebase Storage to host files from my site. Just to manage downloads and uploads from users. Is this correct?
Firebase Hosting uses a powerful global CDN to make your site as fast as possible. Any requested static content is automatically cached on the CDN. If you redeploy your site's content, Firebase Hosting automatically clears all your cached static content across the CDN until the next request.
You can't store files to Firebase Cloud Firestore instead you can use the combination of Firebase Storage and Firebase Cloud Firestore to active the desired functionality. Firebase Storage is to storage files and download from it.
Firebase already does cache the database locally, before it fetch real-time data from the server, so the problem is not as severe. But if you want to do better caching, use Glide, Glide caches images and you can specify time signatures so it re-fetches images only if they are updated.
cacheControl
for Storage : https://firebase.google.com/docs/reference/js/firebase.storage.SettableMetadata#cacheControl
You'll have better serving with Hosting, and deployment with the firebase CLI is extremely simple. I think by default the Cache-Control on images in Hosting is 2 hours, and you can increase it globally with the .json.
https://firebase.google.com/docs/hosting/full-config#headers
Hosting can scale your site and move it to different edge nodes closer to where the demand is. Storage is limited to buckets, but you can specify a bucket for Europe, one for China, on for North America, etc..
Storage is better for user file uploads and Hosting was for static content (although they are rolling out dynamic Hosting with cloud functions I think)
Putting the pieces together for any future references here
First,
// Create file metadata to update
var newMetadata = {
cacheControl: 'public,max-age=4000',
}
Then,
storageRef.put(file, newMetadata)
storageRef.updateMetadata(yourMetadata)
might be the solution you need.
https://firebase.google.com/docs/storage/web/file-metadata#update_file_metadata
or
storageRef.put(file, yourMetadata)
https://firebase.google.com/docs/storage/web/upload-files#upload_files
To complement the answer, you can also use a service worker, maybe with workbox, with a cacheFirst
strategy to cache all images into the user browser. Then, after first cache, the images will be load from local cache first.
If there's no cache, then the images will be requested from Firebase Storage, where the images can also be cached if you specified the cacheControl
property in file metadata or if you is using Firebase Hosting with custom header Cache-Control
for images.
Also, Is possible to change the cache control of an existent resource accessing Google Cloud Console. (So, don't need to reupload with the cache metadata)
Access the console and go to 'Cloud Storage'. Browse to your bucket and file, where you find 'edit metadata'.
Here, you can put the cache control policy:
Use Serviceworker for that.
You can save the urls without the token in cache and fetch them later.
This way changes in tokens will not affect you caching.
To cache without token, use something like
cacheUrl = url.origin + url.pathname.substr(0, url.pathname.length - urlPath.length) + urlPath;
and then cache.put(cacheUrl, response);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With