Firebase-tools: Emulated callable function throws cors error

Created on 12 May 2019  路  24Comments  路  Source: firebase/firebase-tools

[REQUIRED] Environment info


firebase-tools: >=6.9.0


Platform: macOS

[REQUIRED] Test case

// functions/src/index.ts
import * as functions from 'firebase-functions'
export myCallable = functions.https.onCall((data, ctx) => {
  console.log("I'm inside the function")
  return 'ok'
})

// app/src/firebase.ts
import firebase from 'firebase/app'
import 'firebase/functions'

if (!firebase.apps.length) {
  firebase.initializeApp({})
}

if (process.env.NODE_ENV === 'development') {
  firebase.functions().useFunctionsEmulator('http://localhost:5001')
}

export default firebase
// app/src/page.tsx

import React, { useState, useEffect } from 'react'
import firebase from './firebase'
import Loading from './loading'

const Page: React.FC = function Page() {
  const [loaded, setLoaded] = useState(false)
  async function load() {
    const myCallable = firebase.functions().httpsCallable('myCallable')
    const result = await myCallable()
    setLoaded(true)
  }
  useEffect(() => {
    load()
  }, [])
  return (
    <div className='bg-gray-300'>
      <h1 className='my-8'>Page</h1>
      {loaded ? <div>works</div> : <Loading />}
    </div>
  )
}

export default Page

[REQUIRED] Steps to reproduce

Run firebase serve --only functions with firebase-tools versions 6.9.0 and above

[REQUIRED] Expected behavior

It doesn't result in error, like 6.8.0 doesn't.

[REQUIRED] Actual behavior

Access to fetch at 'http://localhost:5001/my-project/us-central1/myCallable'
from origin 'http://localhost:3000' has been blocked by CORS policy: 
Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

index.cjs.js:70 Uncaught (in promise) Error: internal
    at new HttpsErrorImpl (index.cjs.js:70)
    at _errorForResponse (index.cjs.js:191)
    at Service.<anonymous> (index.cjs.js:711)
    at step (tslib.es6.js:194)
    at Object.next (tslib.es6.js:125)
    at fulfilled (tslib.es6.js:78)
HttpsErrorImpl @ index.cjs.js:70
emulator-suite bug

Most helpful comment

Hello there
I麓m having this issue also

image

Any definitive solution?

All 24 comments

Thanks for filing this, I specifically added code to prevent this so I'm
surprised. I'll investigate on Monday.

Also this:

$ firebase functions:shell

firebase > myCallable('some data')
ReferenceError: myCallable is not defined

edit: I guess this is probably related:

https://github.com/firebase/firebase-tools/issues/1243

@cdock1029 The shell regression is known but thanks for bringing it up again! We're investigating and will have a fix this week.

So this is what we do already:

      // Allow CORS to facilitate easier testing.
      // Source: https://enable-cors.org/server_expressjCannot understand what targets to deploys.html
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

I was not able to reproduce this issue. I set up a very single Firebase Hosting page like this:

<!DOCTYPE html>
<html>
  <head>
    <script defer src="/__/firebase/6.0.2/firebase-app.js"></script>
    <script defer src="/__/firebase/6.0.2/firebase-functions.js"></script>
    <script defer src="/__/firebase/init.js"></script>
  </head>
  <body>
    <script>
      document.addEventListener('DOMContentLoaded', async function() {
        console.log('DOMContentLoaded');

        let functions = firebase.functions();
        functions.useFunctionsEmulator('http://localhost:5001');

        try {
          let myCallable = functions.httpsCallable('myCallable');
          let result = await myCallable();
          console.log('Success');
          console.log(result);
        } catch (e) {
          console.warn('Failure');
          console.warn(e);
        }
      });
    </script>
  </body>
</html>

When I do firebase serve and then go to localhost:5000 the call to callable functions works fine. Is there some critical difference between my environment and the test case posted?

Oh wait I think I see the issue.

Yes I can reproduce this. It only happens when you are signed in which changes the headers that callable functions sends.

Yes I was just going to reply that it is the authorization header which seems to not be allowed.

And, being signed in is the only reason to use callables no? ;)

@cdock1029 so I can easily get this to work in the emulator, but in production it doesn't seem like the GCF backend is setting CORS headers. I get:

Access to fetch at 'https://us-central1-fir-dumpster.cloudfunctions.net/myCallable' from origin 'http://localhost:5000' has been blocked by CORS policy: 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.

I assume I must be doing something WAY wrong here. My goal is to make local development easy but also not set people up to fail when they get to prod.

Hmm.. it's been working pre-6.9.0 though? The sudden incompatibility seems weird.

@cdock1029 figured it out. Fix coming in https://github.com/firebase/firebase-tools/pull/1286

Hi,
On my env, got latest master source, then installed, then run
It seems... I still have the issue

i  functions: HTTP trigger initialized at http://localhost:5000/evctest-aa82f/us-central1/dumpQuery
i  functions: HTTP trigger initialized at http://localhost:5000/evctest-aa82f/europe-west1/safejsTest
!  Ignoring trigger "onUserCreate" because the service "firebaseauth.googleapis.com" is not yet supported.
!  Ignoring trigger "onUserDelete" because the service "firebaseauth.googleapis.com" is not yet supported.
!  Ignoring trigger "onQueueCreate" because the Cloud Firestore emulator is not running.
!  Ignoring trigger "onQueueDelete" because the Cloud Firestore emulator is not running.
!  Ignoring trigger "onSupplierCreate" because the Cloud Firestore emulator is not running.
!  Ignoring trigger "onSupplierDelete" because the Cloud Firestore emulator is not running.
i  functions: HTTP trigger initialized at http://localhost:5000/evctest-aa82f/europe-west1/actionCall
i  functions: HTTP trigger initialized at http://localhost:5000/evctest-aa82f/europe-west1/actionRequest
 ****************** Hello FLE ****************
i  functions: Beginning execution of "safejsTest"
!  Default "firebase-admin" instance created!
>  events.js:183
>        throw er; // Unhandled 'error' event
>        ^
>
>  Error: listen EACCES C:\Users\FLELIR~1\AppData\Local\Temp\firebase_emulator_invocation_24520.sock
>      at Server.setupListenHandle [as _listen2] (net.js:1343:19)
>      at listenInCluster (net.js:1401:12)
>      at Server.listen (net.js:1496:5)

I put a "tracker" in the file src/emulator/functionsEmulator.ts to ensure I was using the latest file:

      // Sources:
      //  * https://enable-cors.org/server_expressjCannot understand what targets to deploys.html
      //  * https://stackoverflow.com/a/37228330/324977
      res.header("Access-Control-Allow-Origin", "*");

      console.log(` ****************** Hello FLE **************** `);

      // Callable functions send "Authorization" and "Content-Type".
      res.header(

Of course, I'm not an expert and likely I did something wrong. But weird my tracker tells me I have latest file, and the issue still here.

Happy to retest here on my win10 platform

@samtstern I have a very similar issue which occurs on both 6.9.0 as well as 6.10.0.

The sample app is almost identical, however I receive the following error:

Access to fetch at 'http://localhost:5001/myapp/us-central1/myCallable' 
from origin 'http://localhost:8080' has been blocked by CORS policy: 
Request header field firebase-instance-id-token is not allowed by 
Access-Control-Allow-Headers in preflight response.

index.cjs.js:59 Uncaught (in promise) Error: internal
    at new HttpsErrorImpl (index.cjs.js:59)
    at _errorForResponse (index.cjs.js:154)
    at Service.<anonymous> (index.cjs.js:526)
    at step (tslib.es6.js:97)
    at Object.next (tslib.es6.js:78)
    at fulfilled (tslib.es6.js:68)

When I manually add the Firebase-Instance-Id-Token string to Access-Control-Allow-Headers in the source, the issue is resolved.

@fngrl thanks for letting me know. Clearly I don't quite understand the behavior of Functions in prod with respect to CORS. I tried to model the emulator based on what I saw with a production callable ... Let me talk to someone who worked on the backend team and make sure we get this right once and for all.

Got a better fix for this in #1335

Hello there
I麓m having this issue also

image

Any definitive solution?

I also have this issue. However, for me it's not only the emulator, but also the deployed functions after I changed the region.

plus 1 for getting this error after changing the region of a cloud function (to europe-west2) just like @CiriousJoker

By the way, I fixed it after I realized that I was creating functions on server1 and access from server2.

I had the same problem my function name was 20 characters i reduced it to something like 9 characters and it fixed it

I see the original issue is for firebase serve.

But I still have this CORS problem when using
firebase emulators:start

馃憤 I just started having this problem today. I was developing yesterday with no issue, no versions have changed that I can see. Multiple branchs I'm sure it was working on is no longer working now either.

@qqhann or @Andrew1431 if you're experiencing this in firebase emulators:start please open a new issue so we can debug!

The same thing is happening here, nothing changed, the only thing changed is that I deployed the callable functions to our prod, restarted the machine and now it won't work locally in the emulator:

Access to fetch at 'http://192.168.0.5:5001/ourappname-dev/us-central1/createQRCode' 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.

FIxed, my script to deploy changes the project firebase use project_id and I forgot to change back to the dev I use in the emulator.

@MorenoMdz doh! Thanks! I've hit this problem twice now and I keep forgetting the issue is a simple pilot error but hard to detect...

Sometimes I manually switch between two different firebase configurations (prod and dev in my case). My (flutter) app is configured to use the dev firebase project instance with the local emulator. After doing some prod project configuration I forgot to switch back to dev so, for me the fix is simple... don't forget to switch back to the dev config:

firebase use dev

馃う

@samtstern Perhaps the emulator could remind/warn us of the effective firebase configuration in use when it is started?

Was this page helpful?
0 / 5 - 0 ratings