9

SOLVED - See my answer below.

Callable function is causing CORS error like this:

Access to fetch at 'https://us-central1-careerhub-a50a2.cloudfunctions.net/createUser' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Function code:

exports.createUser = functions.https.onCall((data, context) => {
    const email = data.email
    const password = data.password

    admin.auth().createUser({
        email: email,
        emailVerified: false,
        password: password
    }).then((res) => {
        return {
            response: res
        }
    }).catch((err) => {
        return {err}
    })

})

Client-side:

    const handleAddUser = () => {
      let pswd = passwordGen(7)
      const createUser = firebase.functions().httpsCallable('createUser');
      createUser({email: email, password: pswd}).then(function(result) {
        let res = result.data
        console.log(res)
      }).catch(function(error) {
        console.log(error.code)
      })

    }

package.json

{
  "name": "careerhub-web",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "antd": "^4.0.2",
    "firebase": "^7.10.0",
    "node-sass": "^4.13.1",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-email-editor": "^1.0.0",
    "react-reveal": "^1.2.2",
    "react-router-dom": "^5.1.2",
    "react-scripts": "3.4.0",
    "recharts": "^2.0.0-beta.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

This error persists even if I'm offline.

Things I've tried:

  1. Updating firebase SDK
  2. Adding "proxy" : '...' to package.json
  3. Using basic functions from the cloud functions guides
  4. Deleting firebase app and deleting function and redeploying
  5. Adding const cors = require('cors')({origin: true}); to function
Tom West
  • 151
  • 1
  • 6
  • 1
    You should add cors in your firebase function. check this https://stackoverflow.com/questions/57326098/enable-cors-in-firebase-cloud-function – David Agustin Melgar Apr 01 '20 at 13:43
  • @DavidAgustinMelgar forgot to add that I had tried this to no success. Tried again to be certain with no luck. – Tom West Apr 01 '20 at 13:52

1 Answers1

6

The error turned out to be a poorly documented change on Google's end around IAM permissions, which are not clearly accessible via the Firebase console.

The Cause:

Cloud functions were forbidding access to the function. Newly created functions did not have a Cloud Functions Invoker. This change was implemented on Jan 15, 2020

Solution:

Create Cloud Functions Invoker and set to allUsers. https://cloud.google.com/functions/docs/securing/managing-access-iam

Tom West
  • 151
  • 1
  • 6
  • 1
    ALL DAY. I just spent all day trying to figure this out. Thank you for coming back and posting the solution. for anyone else that stumbles upon this add "allUsers" as a member of the function and select "Cloud Functions Invoker" as the role. – Ming the merciless Nov 16 '20 at 22:54
  • This worked for me but with permission set to allAuthenticatedUsers and role set to Cloud Functions Admin. Cloud functions Invoker wasn't enough. Is this correct? – jmc42 Mar 22 '21 at 16:18
  • this solution is for google not firebase interface. firebase interface does not have the option to change access to AllUsers – kirill_igum Feb 15 '22 at 22:38
  • If you are using firebase interface, you should just add Cloud Functions Invoker role to adminsdk entity and don't forget to redeploy or manually delete functions from Cloud Functions and deploy again to apply changes in permissions – The Mauler Jun 21 '22 at 15:45