firebasecorsgoogle-cloud-storagefirebase-storagegsutil

Firebase-Storage Access to fetch at '..' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource


I am tying to load an image using the following code:

const blob = await fetch(
    "https://firebasestorage.googleapis.com/...?alt=media"
  )
  .then((r) => r.blob())
  
const reader = new FileReader();

reader.onload = function() {
  const objectUrl = reader.result as string;
  // do something with object url
};

reader.readAsDataURL(blob);

But, I get the following CORS blocked error in the browser console:

Access to image at 'https://firebasestorage.googleapis.com/...?alt=media' from origin 'http://localhost:5000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

If I paste the url in browser's address bar, the image loads successfully which implies that the resource exists and the resource path is correct.

I looked up for how to fix this error and found the following stackoverflow posts:

  1. Firebase Storage and Access-Control-Allow-Origin
  2. Firebase Storage Access to fetch at '..' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

Both the above posts recommend that I create the following CORS config and update it using the gsutil CLI tool.

[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]

I opened Cloud Shell from my GCP account and used the following gsutil command to update the CORS configuration of my bucket.

$ gsutil cors set cors.json gs://my-bucket-name

I even performed a read query to see if the CORS config was updated correctly and I got the following result:

$ gsutil cors get gs://my-bucket-name
[{"maxAgeSeconds": 3600, "method": ["GET"], "origin": ["*"]}]

I thought adding "OPTIONS" method in the config might help, but no luck.

I hope I am not doing something silly. Any pointers to how I can debug this would also be appreciated.

Following is the snapshot of my network tab having more details about the request:

enter image description here


Solution

  • After banging my head over this issue for a couple of days, I thought of trying to reproduce this issue with a brand new firebase project and in incognito window and I wasn't able to. So, I tried to run my original project in incognito and to my surprise, I didn't see any CORS issue there.

    I remembered that my images come with a cache control header with maxage as 1 year so I hypothesized that maybe the browser has cached the previous CORS blocked response for a year and it was indeed true because appending a dummy query parameter to the url made the fetch request to succeed. So, to fix this issue, I disabled the cache in the browser and refreshed the page and, surprise surprise, everything worked. Once everything works, you can re-enable the cache because browser must have invalidated the old cached responses.

    enter image description here

    So, if you were only getting this issue during your development phase, you could easily fix this by disabling cache for 1 page refresh and then re-enabling it. However, if you have already deployed this to production and your users are seeing this issue, you could consider changing the urls for the images so that browser is forced to make a new request or a hacky fix would be to add a dummy query parameter at the end of the url.