firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.81k stars 884 forks source link

useFunctionsEmulator not working with region #2510

Open ThewBear opened 4 years ago

ThewBear commented 4 years ago

[REQUIRED] Describe your environment

[REQUIRED] Describe the problem

Emulator url will be ignored and call to cloudfunctions.net instead when setting region.

Relevant Code:

firebase.functions().useFunctionsEmulator("http://localhost:5001");

// This will call to cloudfunctions.net
firebase.app().functions("asia-east2").httpsCallable(<FnName>);

// This will call to localhost
firebase.app().functions().httpsCallable(<FnName>);
google-oss-bot commented 4 years ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

rommelpe commented 4 years ago

Thanks for reporting, @ThewBear. It looks like an intended behavior as it's meant to test the function locally, the region isn't being observed. It's not until you deploy it that you can invoke it in the given region. The deployed URL should have the region in the hostname part of the URL, not in the path as you get the emulator.

ThewBear commented 4 years ago

So my current workaround is

if (process.env.NODE_ENV === "development") {
  firebase.app().functions().httpsCallable(<FnName>);
} else {
  firebase.app().functions("asia-east2").httpsCallable(<FnName>);
}

I think it would be better if I can give a region and firebase ignores it when using emulator. This is already working in firebase-functions.

rommelpe commented 4 years ago

Thanks for letting us know your workaround, @ThewBear. While this is currently an intended behavior, we'll treat this as a feature request and keep this open.

jQrgen commented 4 years ago

+1

binajmen commented 4 years ago

+1 👍

ranga27 commented 4 years ago

+1

elbourki commented 3 years ago

I was using firebase.functions().useFunctionsEmulator(environment.emulator) globally, so to keep the changes to a minimum I used this as a workaround:

firebase.app().functions(environment.emulator ? undefined : 'europe-west1').httpsCallable(<FnName>)
loucou commented 3 years ago

I would like to add that when using automatic app initialization by including: <script defer src="/__/firebase/init.js?useEmulator=true"></script> Only calls to functions located in us-central1 are directed to localhost, calls to other regions go to ...cloudfunctions.net As a consequence we still need to perform some manual initialization over the automatic init:

if (location.hostname === "localhost") {
  firebase.app().functions("europe-west3").useEmulator("localhost", 5001);
}
shu-pf commented 3 years ago

It seems that the specifications of the functions emulator have changed. Currently, when a region is specified in the functions, the url will look like this in the emulator. The region is included in the functions URL.

As mentioned earlier, if you currently try to connect to a region other than us-central1, you will be connected to the production environment. Therefore, we need to change the region of functions so that it can be accessed from the sdk.

This means that the following actions are currently required to run the emulator correctly in projects other than us-central1.

firebase js sdk

if (process.env.NODE_ENV === "development") {
  firebase.app().functions().httpsCallable(<FnName>);
} else {
  firebase.app().functions("asia-east2").httpsCallable(<FnName>);
}

firebase functions

import * as functions from 'firebase-functions';

if (process.env.FUNCTIONS_EMULATOR) {
  functions.region('us-central1');
} else {
  functions.region('asia-northeast1');
}
binajmen commented 3 years ago

This is working for me:

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.app().functions('europe-west1').useEmulator('localhost', 5001)
  // ...
}

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

src: https://github.com/firebase/firebase-tools/issues/3519#issuecomment-865173539

shu-pf commented 3 years ago

@binajmen It looks like this bug has been fixed. Thanks to your link, I was able to get the emulator to work properly !

turbotobias commented 3 years ago

In case anyone is looking for setting region with functions + emulator in Firebase 9

import { initializeApp } from "firebase/app"
import { getFunctions, connectFunctionsEmulator } from "firebase/functions"
import { config } from "~/api/firebase/config"

const firebaseApp = initializeApp(config)
const functions = getFunctions(firebaseApp, "europe-west1")

if (import.meta.env.DEV) connectFunctionsEmulator(functions, "localhost", 4003)
3zzy commented 8 months ago

@turbotobias wonder if its the same for Firebase v10?