David Y. Stephenson
David Y. Stephenson

Reputation: 980

Using locally emulated https.onCall Firebase functions in locally hosted Firebase application

I am writing a Firebase application using the node SDK and vanilla JavaScript on the client side. I am using Firebase Cloud Functions to implement a server that receives requests for my page routes and returns rendered HTML with the https.onRequest method. I am also using Cloud Functions to handle client-server interaction with the https.onCall method.

I develop locally using the firebase serve command. When developing locally, my client seems ignores my local onCall functions, instead calling the route for the deployed onCall functions. I am forced to deploy my onCall functions in order to see changes locally. If I do not deploy each change, my local app will not show any changes to onCall functions. This happens whether I run firebase serve or firebase serve --only=hosting,functions.

When I run my app locally with firebase serve, the pages are generally hosted at localhost:5000. The functions are hosted at localhost:5001. If I call a cloud function on one of these locally hosted pages, like firebase.functions().httpsCallable('functionName') and check the Network panel in my developer tools, I can see the Request URL is https://us-central1-<app-name>.cloudfunctions.net/<functionName>, instead of localhost:5001/<app-name>/us-central1/<functionName>.

This is frustrating me because it means I have to deploy my functions to test each change, rather than testing my local functions through my locally hosted web application.

Have I configured something incorrectly? How can I get my locally hosted app to use my locally emulated onCall cloud functions?

I am not making a single page application or using any view frameworks.

Upvotes: 10

Views: 2244

Answers (2)

Djulian
Djulian

Reputation: 36

Updated version for Firebase v9.x.x:

import { getApp } from "firebase/app";
import { getFunctions, connectFunctionsEmulator, httpsCallable } from "firebase/functions";

const functions = getFunctions(getApp());
connectFunctionsEmulator(functions, "localhost", 5001);

httpsCallable(functions, 'helloWorld')({foo: "bar"}).then((res) => ...)

Upvotes: 2

Henrik Wassdahl
Henrik Wassdahl

Reputation: 1140

It seems like Firebase has yet to implement a solution to point to the local server, so I came up with a little hack. Include the below snippet where you initialize your Firebase project. Hope it helps!

if (process.env.NODE_ENV === 'development') {
  firebase.functions()._url = function (name) {
    return `${process.env.API_URL}/${name}`
  }
}

EDIT: Like goker.cebeci commented below, the correct way to connect to your local emulator is to use functions.useFunctionsEmulator('http://localhost:5001') (change http://localhost:5001 to whatever address your local emulator is running on)

The updated code looks like this:

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

Upvotes: 16

Related Questions