36

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.

Network stats

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?

bodruk
  • 3,242
  • 8
  • 34
  • 52

6 Answers6

18

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)

James Poag
  • 2,320
  • 1
  • 13
  • 20
  • Thanks, bro! You helped a lot! :D – bodruk May 23 '17 at 02:13
  • 5
    In this answer, "Hosting" means Firebase Hosting, and "Storage" means Firebase Storage. Both are services provided by Firebase. Just for clarity. – user2875289 Mar 01 '18 at 01:05
  • I had the same issue and found the solution to serve Cloud Storage files by Firebase Hosting. Now we get the benefits from both products. :) https://dev.to/dbanisimov/building-image-cdn-with-firebase-15ef – Tim Wong Feb 25 '20 at 01:20
  • FYI - bandwidth on 'hosting' plan is more expensive than the 'storage' equivalent plan. – Ronen Rabinovici Aug 21 '22 at 09:33
  • telling people to potentially abandon their stack and use firebase hosting is not good (assuming the host is bundled in with the stack like with Vercel + Next) – John Miller Aug 18 '23 at 03:41
11

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)

Max
  • 834
  • 8
  • 19
5

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

Ruslan
  • 134
  • 1
  • 10
4

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:

Edit metadata for object

Vagner Gon
  • 595
  • 9
  • 23
  • 2
    So, if you tried (like me) to find it in the Firebase console - it's not there. The key is to access the file through Google's Cloud Console and NOT through the firebase console... – Ronen Rabinovici Aug 21 '22 at 10:02
3

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.

  • 1
    I'm using workbox for this as well, however you may need to employ the staleWhileRevalidate or networkFirst strategies in workbox, because you are requesting a third party file. https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests – Alex Kimoto Mar 22 '18 at 13:37
1

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);

Haim763
  • 1,514
  • 2
  • 10
  • 14