Setup CORS in Firebase Functions
November 27, 2018 • 1 minute to read
In one of my last project, I was using Firebase Functions. I did love to use them, but it’s quite hard to find some solution on this new stuff. One think I found pretty hard to get it work was the CORS of my project. When I use Express I can use the packages CORS, but here we don't have a server. Firebase Functions are just simple function. Yes, they can be use as HTTP endpoint etc, but they go sleep after being trigger and completed the job. The thing also is when I add this CORS package, I add it as middleware. Here if, I want to use a middleware I can but I will need to add express and wrap the full server with it.
Yes, that will have been so much easier I know. But I want to fix that without going to this path. So after searching on StackOverFlow a lot and try/error I finally figured out :).
First, we need to add this CORS package. Yes I know you can set it without it, but for this tutorial, I will show with it. Also the example I will show make use of Typescript. You can use javascript without any problem also :)
1yarn add cors
After inside your index.ts
file or whatever file where you import your function just import CORS and initialize it.
1import cors from 'cors'23const corsHandler = cors({4 origin: [5 'http://localhost:3000',6 // Staging URL7 // PROD URL8 ],9}****)
We will need to add this corsHandler
function to your functions.
1export const hello = functions.https.onRequest(2 (req: functions.Request, res: functions.Response) => {3 // @ts-ignore4 // tslint:disable-next-line:no-empty5 corsHandler(req, res, async () => {6 await // my logic78 res.status(200).json({ message: 'Yes cors work' })9 })10 }11)
As you can see I pass to my corsHandler the request and response object. This way I can setup the cors pretty easily. I know in some place we see
1export const hello = functions.https.onRequest(2 async (req: functions.Request, res: functions.Response) => {3 // @ts-ignore4 // tslint:disable-next-line:no-empty5 corsHandler(req, res, () => {})67 await // my logic89 res.status(200).json({ message: 'Cors will work, but we will received an error of headers' })10 }11)
Like you can see, not a lot of difference. But yes we have one if I do this in the firebase logs I received. Error: Can't set headers after they are sent.
Alternative
For sure with this way, this will get painful to add CORS everywhere. That's why you can then use express to make your life easier.
1import express from 'express';2import cors from 'cors';34const app = express();56app.use(cors({7 origin: [8 'http://localhost:3000',9 // Staging URL10 // PROD URL11 ],12})1314app.post('/hello', async (req: functions.Request, res: functions.Response) => {15 // logic here16}));1718export const app = functions.https.onRequest(app);
Much simpler, YES sure. But now your endpoint will look like <yourdomain>/app/...
. You can maybe go with like a v1
as export so this will look like versioning but hey here it's your choice :)
End word
Hope this helps you fix this issue. For me, that takes a bit more time then on a regular server. But now it work :).