Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callable function not working in emulator (CORS issue + HttpsErrorImpl error) #3519

Closed
binajmen opened this issue Jun 21, 2021 · 3 comments
Closed

Comments

@binajmen
Copy link

binajmen commented Jun 21, 2021

Environment info

firebase-tools: 9.13.1

Platform: macOS

Test case

I'm setting up my firebase client as below, specifying useEmulator when in development:

// client.ts

import firebase from 'firebase/app'
import 'firebase/firestore'
import 'firebase/functions'
import 'firebase/auth'
import 'firebase/storage'

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

if (process.env.NODE_ENV === "development") {
  firebase.firestore().useEmulator('localhost', 8080)
  firebase.functions().useEmulator('localhost', 5001)
}

firebase.auth().useDeviceLanguage()

export default firebase

I have multiple cloud functions, including callables (which cause me problems):

// index.ts – cloud functions
...

export const createOfflineOrder =
  functions.region("europe-west1") // <---- notice "europe-west1"
    .https.onCall(async (data, context) => {
      return await (await import("./order/create")).createOrderWithNoPayment(data, context)
    })

I call this function in the client as below:

const isDev = process.env.NODE_ENV === "development"
const functions = firebase.app().functions(isDev ? undefined : 'europe-west1')

let createOfflineOrder = functions.httpsCallable('createOfflineOrder')
createOfflineOrder(data)
  .then(result => {
    ...
  })
  .catch(error => {
    console.error(error)
  })

Steps to reproduce

This is a Next.js project that is private (not mine, can't share or give access to repo to reproduce)

Expected behavior

To work as it was working previously

Actual behavior

What was working previously is not anymore.

I have in the network tab of Chrome a CORS error. The cURL equivalent of what is happening behind the scene (taken from the network tab as well) is:

curl 'http://localhost:5001/project_name/us-central1/createOfflineOrder' \
  -H 'sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"' \
  -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZC...' \
  -H 'Referer: http://localhost:3000/' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36' \
  -H 'Content-Type: application/json' \
  --data-raw '{"data":{ ... }}' \
  --compressed

You'll notice it is using us-central1 instead of europe-west1. But this was working before, so it could be but shouldn't be the reason. Or is it?

This is (logically?) followed by a 404:

// request

OPTIONS /project_name/us-central1/createOfflineOrder HTTP/1.1
Host: localhost:5001
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: fr,en;q=0.9,nl;q=0.8

// response

HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 1130
ETag: W/"46a-6qZ+Me9cTHgI/XZXWyykHNdXIj0"
Date: Mon, 21 Jun 2021 16:06:49 GMT
Connection: keep-alive
Keep-Alive: timeout=5

The promise is rejected and I have the following error:

Error: internal
    at new HttpsErrorImpl (index.esm.js?f038:54)
    at _errorForResponse (index.esm.js?f038:149)
    at Service.eval (index.esm.js?f038:603)
    at step (tslib.es6.js?ef9e:102)
    at Object.eval [as next] (tslib.es6.js?ef9e:83)
    at fulfilled (tslib.es6.js?ef9e:73)

What is very strange is that it call http://localhost:5001/project_name/us-central1/createOfflineOrder with us-central1 whereas it should use europe-west1, but I supposed it doesn't matter when using the emulator + this setting was working properly in my last release (2-3 weeks ago).

Any help would be greatly appreciated as I really can't understand what is happening here..

@samtstern
Copy link
Contributor

samtstern commented Jun 21, 2021

@binajmen since the launch of the Emulator Suite we had a bug where we ignored function regions in emulation. We fixed that in a recent release, but this means that some scripts (like yours) which depended on the bug broke.

Try this:

if (process.env.NODE_ENV === "development") {
  firebase.firestore().useEmulator('localhost', 8080)
  firebase.app().functions('europe-west1').useEmulator('localhost', 5001) // <-- added region
}

const functions = firebase.app().functions('europe-west1'); // <-- Removed the `dev` ? check

The useEmulator setting affects one FirebaseFunctions instance so it's important to use firebase.app().functions('europe-west1') in both places.

@samtstern samtstern added the Needs: Author Feedback Issues awaiting author feedback label Jun 21, 2021
@binajmen
Copy link
Author

binajmen commented Jun 21, 2021

Hi @samtstern,

Thank you for this quick reply.

I'm having the following error:
Argument of type '"europe-west1"' is not assignable to parameter of type 'App | undefined'. ts(2345)

firebase.functions('europe-west1').useEmulator('localhost', 5001)

I did a yarn upgrade firebase-functions to make sure I have the latest version (firebase-functions@3.14.1).

EDIT: just noticed you changed to firebase.app().functions(...). Let me try it ;)

@google-oss-bot google-oss-bot added Needs: Attention and removed Needs: Author Feedback Issues awaiting author feedback labels Jun 21, 2021
@binajmen
Copy link
Author

@samtstern Thank you !!!

To be honest I've seen so many solutions out there (here and on SO) that I was a bit lost. Hope this thread will help someone else.

Cheers !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants