Enabling CORS in Firebase Functions

After struggling really hard to make a simple proxy in Firebase Functions (see my post), I realized I also needed to enable CORS.

CORS Documentation

Let's take a look at the documentation over at MDN. Apparently, if I want to whitelist any domain, I could set the response header:

Access-Control-Allow-Origin: *

So I added this to the response:

(res: http.IncomingMessage) => {
  response.setHeader("Content-Type", "application/json; charset=utf-8");
  response.setHeader("Access-Control-Allow-Origin", "*");
  res.pipe(response);
}

I then ran it locally with npm run serve, and tried to run my Flutter Web app. It worked!!

Making it work in production

So I ran npm run deploy and tried it again. This time it did not. If I take a look at the response headers, I do not see my CORS header anywhere:

alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
cache-control: private
content-encoding: gzip
content-length: 496
content-type: application/json; charset=utf-8
date: Wed, 15 Mar 2023 02:23:31 GMT
function-execution-id: nuzt96vqyr1d
server: Google Frontend
x-cloud-trace-context: a677ce5e19ada6249727f322e1a6c8aa;o=1
No Access-Control-Allow-Origin header.

Googling a bit brought me to this StackOverflow post. The most upvoted answer suggests to use the cors npm package and to enable all domains, essentially doing the same as using the wildcard I set manually.

One person also mentions:

google cloud functions do not allow the wildcard origin.

And they also shared this link: https://cloud.google.com/functions/docs/writing/write-http-functions#cors.

I did not see any mention of wildcards being disallowed though.

Still, it does not hurt to try setting the domain. So I did:

(res: http.IncomingMessage) => {
  response.setHeader("Content-Type", "application/json; charset=utf-8");
  response.setHeader("Access-Control-Allow-Origin", "https://mydomain.app");
  res.pipe(response);
}

I built my webapp and deployed both the webapp and the function:

flutter build web
# Deploys both the functions to Firebase Functions and the webapp to Firebase Hosting.
firebase deploy

I tried it, and indeed it worked.

I wish the local emulator behaved more closely to what's running in production.