Firebase Callable Function + CORS

JavascriptFirebaseGoogle Cloud-Functions

Javascript Problem Overview


I'm trying to call a callable Cloud Function from my app, but I'm facing CORS issues. enter image description here

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

Javascript Solutions


Solution 1 - Javascript

For anybody else who has arrived here searching firebase callable functions cors errors, here's my checklist:

  1. Ensure the function is deployed.
  2. Ensure the function name is correct. I was calling recalculatY when it should have been recalculateY. Got a cors error for some reason.
  3. 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.
  4. 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 - Javascript

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:

> https://cloud.google.com/functions/docs/securing/managing-access-iam#allowing_unauthenticated_function_invocation

Solution 3 - Javascript

I had this problem with some of my Firebase functions but not others. I eventually fixed it by doing this:

  1. Commenting the function out in index.js
  2. Running firebase deploy
  3. Entering y at the prompt to delete the function
  4. Waiting for 5 to 10 minutes
  5. 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 - Javascript

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

Solution 5 - Javascript

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 6 - Javascript

For those facing this error after enabling firebase on an existing GCloud project, there is some complexity which is not taken care of automatically as it would be if it were just a firebase app.

I had this specific problem because I wanted my firebase function to be publicly accessible, but you have to specifically configure this if you're using google's Cloud Functions.

Here are the steps to fix:

  1. Go to the cloud function tab
  2. Select your cloud function (check box)
  3. Click "Add members" under Permissions tab in the right side
  4. Enter "allUsers"
  5. under "New memebers" Select Role as "Cloud Functions -> "Cloud Functions Invoker"
  6. Save
  7. Test your cloud function by just pasting it in the browser

Cheers

Solution 7 - Javascript

If none of the above is helping: In my case the reason was that I havent correctly set up my regions. This can especially happen when using 3rd party libraries.

Solution 8 - Javascript

I previously had deployed my function as an HTTP function (https.onRequest), then switched to a callable function (https.onCall). Firebase did not recognize this change.

I solved the problem by removing the function and deploying without it, then putting the function back in and deploying again.

Solution 9 - Javascript

If you are using multiple environments (Firebase Projects) to separate development and production (i.e Project-dev, Project-prod), make sure you have switch to the desirable environment. In my case, running this worked:

firebase use default

Solution 10 - Javascript

I had the same issue. My solution was to open my Firebase project in https://console.cloud.google.com and navigated to cloud functions page.

Look for your function name go to its permission page, and add new role "Cloud Functions Invoker" to "allUsers" member.

Solution 11 - Javascript

For me, I had to allow access to allUsers for the function.

  1. Go to Google Cloud Platform Console Cloud Functions. You can click on the Detailed usage stats in the Functions tab on Firebase Console enter image description here

  2. Go to the Permissions tab

  3. Click Add

  4. Add appropriate permission enter image description here

Solution 12 - Javascript

  1. Errors should be as given in https://firebase.google.com/docs/reference/functions/functions.https.HttpsError
  2. I deployed callable function after changed function name and it's working.

Solution 13 - Javascript

I got the same error when I tried to create a custom token for signing in a firebase user. I have attached my code below. However, I later discovered that the issue was due to attempting to create multiple tokens, by calling the function several times with the same parameters.

export const getCustomToken = functions.https.onCall((params: any) => {
 return admin.auth().createCustomToken(params).then((token) => {
   return token;
  }).catch((error) => {
    console.log(error);
    return null;
  });
 });

SOLUTION
I solved the issue by first checking that the user is logged out before attempting to sign in. So I suggest that you first check if the user your trying to create already exists. I know this is a bit late but I hope this helps some one else.

this.fireAuth.currentUser.then((signedInAlready) => {
  if (signedInAlready) {
    return this.fireAuth.signOut().then(() => getCustomToken());
  } else {
    return getCustomToken();
  }
});

In your firebase functions you can check for an existing user as follows:

admin.auth().getUserByEmail('your-email').then((userExists) => {
if (userExists) {
  // return user
} else {
  // create a new user
}});

Solution 14 - Javascript

Basically, I did everything mentioned in tones of pages and answers regarding CORS error for onCall cloud functions, from changing the region or manually adding the invoke permission to more obvious ones, nothing worked for me. Just turned the onCall onto OnRequest and it works.

Solution 15 - Javascript

i try every thing - nothing work.

  1. delete all function - not work...
  2. set the cors header - you cant do it in callable function
  3. add the "Cloud Functions Invoker" permission - it was allredy set..
  4. add try catch -didnt help

till i found someone that tald to change the rewrite rules in angular.json only this work for me here is the complete guide from firestore docs - pay attantion - it works only from region us-central1

how to solve CORS on firestore onCall function with context

anoter docs on CORs problem in callable functions

my lib versions

angualr 13

"@angular/fire": "^7.2.0",

"firebase": "^9.4.0",

Solution 16 - Javascript

What worked for me was to remove the region params in my cloud function and then redeploy.

From functions.region("europe-west2").https.onCall(async (data) => {..

to functions.https.onCall(async (data) => {..

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPietro CoelhoView Question on Stackoverflow
Solution 1 - JavascriptAidoView Answer on Stackoverflow
Solution 2 - JavascriptKitsonView Answer on Stackoverflow
Solution 3 - JavascriptiStuartView Answer on Stackoverflow
Solution 4 - JavascriptDavid ConstantineView Answer on Stackoverflow
Solution 5 - JavascriptPietro CoelhoView Answer on Stackoverflow
Solution 6 - JavascriptNikita JerschowView Answer on Stackoverflow
Solution 7 - JavascriptCode SpiritView Answer on Stackoverflow
Solution 8 - JavascriptsteventilatorView Answer on Stackoverflow
Solution 9 - JavascriptWilsonView Answer on Stackoverflow
Solution 10 - JavascriptMoOpView Answer on Stackoverflow
Solution 11 - JavascriptBao PhamView Answer on Stackoverflow
Solution 12 - JavascriptBHAR4TView Answer on Stackoverflow
Solution 13 - JavascriptA JohnsonView Answer on Stackoverflow
Solution 14 - JavascriptKian AghaeiView Answer on Stackoverflow
Solution 15 - Javascriptyehonatan yehezkelView Answer on Stackoverflow
Solution 16 - JavascriptFrederik AggerView Answer on Stackoverflow