Firebase Callable Function + CORS
Solution 1
For anybody else who has arrived here searching firebase callable functions cors errors, here's my checklist:
- Ensure the function is deployed.
- Ensure the function name is correct. I was calling
recalculatY
when it should have beenrecalculateY
. Got a cors error for some reason. - Ensure the function code itself is not throwing an error. Use the emulator to help. This didn't throw a cors error still helpful to know.
- Ensure your regions match - I am using
europe-west2
. I had to both deploy the function with that region, and call it using the region. For a while, I assumed the client would infer the correct region if the function name was correct. That was not the case.
Deploying a callable function to a specific region:
// This is the file in which you define your callable function.
const functions = require('firebase-functions');
...
exports.yourFunc = functions.region('europe-west2').https.onCall(async (data, context) => {
...
})
Calling a function in a specific region from the client (in this case, a vuejs web app):
// In my case, this is a vuex store file, but it is safe to assume this is plain old javascript
import firebase from 'firebase/app'
import 'firebase/functions'
...
firebase.app().functions('europe-west2').httpsCallable('yourFunc')
Note: firebase.app().function...
vs firebase.app.function...
Solution 2
For anyone looking at this post Jan 2020..
Found this answer on Reddit (https://www.reddit.com/r/reactjs/comments/fsw405/firebase_cloud_functions_cors_policy_error/)
Turns out on 15th Jan 2020, Google changed the security settings where all new functions no longer have a Cloud Functions Invoker. This means that all newly created functions will have their access forbidden, thus resulting in a CORS policy block.
Here is how you fix it, as it's not all that obvious:
Solution 3
I had this problem with some of my Firebase functions but not others. I eventually fixed it by doing this:
- Commenting the function out in index.js
- Running firebase deploy
- Entering y at the prompt to delete the function
- Waiting for 5 to 10 minutes
- Removing the comments around the function and running firebase deploy again
Without any changes to the function itself, it now runs without any CORS issues.
Solution 4
My issue was not with CORS, but with my error handler. Instead of rejecting the promise, I've used throw
directly in the catch handler.
catch((err) => {
throw new functions.https.HttpsError('unknown', err.message, err)
})
Solution 5
Probably many will hit this issue with the emulator and cors messages.
I havn't seen my case discussed in any discussion I've seen in Google, I do have seen many "can't reproduce", maybe my case will shade some light:
In my case the issue was that I wasn't running the hosting from the firebase emulator.
When you run your react app via npm start - while the functions run via firebase emulators:start, you will see the Cors errors.
So when testing cloud function calls, rather using npm start, you should do npm run build and then access the app from the emulator...
Search for something like: "hosting: Local server: http://localhost:5000"
few notes -
-
Your functions should also work against the emulator via
const functions = firebaseApp.functions('europe-west3');// lets assume thats your region functions.useFunctionsEmulator('http://localhost:5000');
![Pietro Coelho](https://i.stack.imgur.com/Fd4bk.jpg?s=256&g=1)
Pietro Coelho
Updated on June 12, 2022Comments
-
Pietro Coelho about 2 years
I'm trying to call a callable Cloud Function from my app, but I'm facing CORS issues.
I can't enable Cors since I don't have access to the request and response on the onCall function. This is my function:
exports.UserInvitation = functions.https.onCall((data, context) => { const email = data.email return new Promise((resolve, reject) => { admin.auth().createUser({ email: email, emailVerified: false, password: password }).then(resolve).catch((err) => { console.error(err.code) reject(new functions.https.HttpsError(err.code, err.message)) }) }) })
And this is how I call it:
functions.httpsCallable('UserInvitation')({ email: this.input.value }).then((data) => { console.log('Sent invitation:', data) })
Firebase-functions package.json:
{ "name": "functions", "description": "Cloud Functions for Firebase", "scripts": { "serve": "firebase serve --only functions", "shell": "firebase functions:shell", "start": "npm run shell", "deploy": "firebase deploy --only functions", "logs": "firebase functions:log" }, "dependencies": { "bluebird": "^3.5.1", "firebase-admin": "~5.12.0", "firebase-functions": "^1.0.1" }, "private": true }
WEB SDK Firebase version: 4.13.1
-
mesqueeb about 4 yearsthat seems extremely weird to me. Rejecting inside a promise that you are returning in the cloud function, feels to me like it's the exact same thing as throwing...
-
moto about 4 yearsGood lord. What a mess of a bug to find. Thank you!
-
Kishan Oza about 4 yearsbut this will allow all users to call this function I mean I have done that CORS error gone but now I can trigger that function from postman with out any headers!! is this the only way @Kitson
-
Kitson about 4 yearsI was using
.https.onCall(async (data, context) => { ... })
and the context has access to teh auth usercontext.auth
. I was then using this to check permissions and throw an error for unauthenticated users. -
akauppi about 4 yearsWhere do you set the regions? I'm using one, but only in the calling: exports.myf = functions.region("europe-west3").https.onCall(...). Is there some other place I should touch?
-
akauppi about 4 yearsThis made it for me! Didn't have region in the calling.
-
Code Spirit about 4 yearsYou can wrap it in your own module and use this instead of the original functions module so you only have to call region once.
-
akauppi about 4 yearsMy problem was solved by @Aido's answer. Needed to also have the browser code tell Firebase which region to use.
-
Séraphin almost 4 yearsBasic checklist... you saved me with "Ensure the function name is correct"
-
Kevin Aung almost 4 yearsThanks for this. It was #1 for me. I thought I had deployed it.
-
Nithin over 3 yearssaved my day. I was gonna edit a whole lot of code.
-
Eric Crescioni over 3 yearsThis is infuriating - for such a big company the docs are all over the place on this topic. How was that not all over the place when it happened? Thank you.
-
tmorell over 3 yearsReference for Angular: github.com/angular/angularfire/blob/master/docs/functions/…
-
Séraphin over 3 yearsSecond time I land here for a typo in my function name. Thanks again!
-
dvdmmc over 3 yearsThanks, this worked for me. Interesting tidbit to add is that I deployed 3 functions at the same time and only 1 had this issue.
-
sceee about 3 yearsUnbelievable, after spending several hours trying all the different solutions here, I deleted every function and redeployed them again and suddenly, they started working without any CORS issues. During that time I was still unsure whether I would also have to do @Nikita's solution for
https.onCall(..)
functions where the user is authenticated (because nothing made them work). Answer is no - complete deletion and redeploy fixed the issue. -
mesqueeb about 3 yearsI tried every single thing in this thread. But this one was the solution for me. Just delete all cloud functions once. Then redeploy and it works again!
-
Félix Paradis about 3 yearsI did something extremely similar: deployed THE EXACT SAME FUNCTION with a different name: great success. Flipped a table and moved on.
-
今際のアリス about 3 yearsI tried all kinds of solutions and yes, the solution was the same for me, just remove all the functions and deploy them again. What the actual.. I've been sitting with this error for hours wondering what and how to solve the issue and then it is just "delete and try again"... feel so stupid.
-
Ryan Prentiss almost 3 yearsSo yeah, I just spent the last 36 hours banging my head against this. Thank you.
-
Suat Karabacak almost 3 yearsI tried every other possible solution ... No offense but I tought this never gonna work because of that I even never tried that but man ... I can say this was the issue. Thank you !
-
Jeyhun Ashurbayov over 2 yearslove you! ❤️ saved my day
-
Ruben over 2 yearsthanks that worked after I started my local emulator again. But do you also know why? What does the firebase environment have to do with my local emulator?
-
Eosis over 2 yearsI will also add my misery to this pile. Deleting the function from the console and re-deploying it was enough to get the functions working. 😑
-
Chrisk8er over 2 yearsI vote for this solution. You saved my day man... Thanks
-
Witt over 2 yearsDeploying to another region, then redeploying to the correct region seems to produce this. Deleting the function in the webAPI and redeploying did the trick. Thanks!
-
Mentor over 2 yearsThis worked, and it makes me sad. In case Google can't find this: this is the fix to CORS errors for onCall firebase functions running into preflight check errors due to a suspected region error in GCP.
-
CiriousJoker over 2 yearsThe cors issue comes because when trying to call a non-existent function redirects you to Google's signin, which has cors enabled ofc
-
Street0 about 2 yearsThis shouldn't be a solution. allUsers leaves it open to Unauthorized access. Answer should consider restricting access to authorized users and consider registering some domain / origin to allow access. Not this
-
Street0 about 2 yearsThis just leaves it again with allUsers invoker which allows for Unauthorized access. People saying it's working again after redeploy is just because the recreated functions has allUsers invoker..
-
Jeroen van de Ven about 2 yearsI'm going to have to start trying this kind of solution earlier on in the troubleshooting process... deploying under a new name fixed it.