12

I am currently working on the way to test my cloud functions locally. I found several ways but using firebase emulator and useFunctionsEmulator() method seemed great. At https://firebase.google.com/docs/functions/local-emulator, they didn't say about the method, but I found it on this url How to test `functions.https.onCall` firebase cloud functions locally?.

However, when I run firebase emulator:start and console.log(firebase.functions().useFunctionsEmulator('http://localhost:5001'), it just showed undefined.

I tried several inputs on the origin but nothing changed. There's so little information on the internet about this, I think that's because this is alpha, so Please help me on this.

BLUE
  • 171
  • 2
  • 10

7 Answers7

7

I got the emulators working and handling local requests by calling the useFunctionsEmulator() method just after initializing the firebase app in the client. Calling it prior caused errors.

firebase.initializeApp(config);
firebase.functions().useFunctionsEmulator("http://localhost:5001");
MathStims
  • 86
  • 1
  • 2
  • Well, like others answered, useFunctionsEmulator should be used after initializeApp to set up things. Thank you for replying and sorry for the late comment. – BLUE Aug 27 '20 at 09:27
  • Would you need to call `useFunctionsEmulator(..)` for every invocation of `functions()`? – Zorayr Dec 02 '20 at 23:16
7

useFunctionsEmulator() doesn't return anything, it's just a setter.

Use it in the following way:

firebase.initializeApp(config);

const functions = firebase.functions();
functions.useFunctionsEmulator("http://localhost:5001");
app_
  • 697
  • 5
  • 12
2

I haven't been able to get useFunctionsEmulator() either but I have a workaround:

I switch my onCall function to an onRequest function like so:

// FROM THIS
exports.exampleFunction = functions.https.onCall((data, context) => {
  // CODE FOR CLOUD FUNCTION
});
// TO THIS
exports.exampleFunction = functions.https.onRequest((request, response) => {
  // CODE FOR CLOUD FUNCTION
});

Then I can serve my function locally with this command firebase serve --only functions which will display a url that I can send requests to via curl, postman or my browser. When I'm done editing the function I switch it back to an onCall function. I hope this helps!

Supra_01
  • 134
  • 1
  • 6
2

For Firebase 9 (modular), use connectFunctionsEmulator instead:

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

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

If you have problem using Firebase 9, follow this guide.

Antonio Ooi
  • 1,601
  • 1
  • 18
  • 32
1

As @app_ wrote, but also this may be worth to someone:

If you use regions, they should only be set for the online call, not the emulated one. This works for me (JavaScript client):

const fns = LOCAL ? firebase.app().functions() :
  firebase.app().functions(functionsRegion);

const log = fns.httpsCallable('logs_v200719');

The LOCAL is set earlier to true if we know we are run against emulated back-end. Please let me know if there's a standard way to sniff that, from the Firebase client.

For developer experience, it would be best if regions are handled the same way locally, meaning one doesn't need the above ternary operator.

firebase-tools 8.6.0, JavaScript client 7.16.1

akauppi
  • 17,018
  • 15
  • 95
  • 120
0

For having troubles calling

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

You can test your onCall method in your app by adding this lines.

FirebaseFunctions functions = FirebaseFunctions.getInstance();
        functions.useEmulator("10.0.2.2", 5001);

or

functions.UseFunctionsEmulator("http://localhost:5004");

Here is my source : https://firebase.google.com/docs/functions/local-emulator

EDIT: Also in node.js you can use

const admin = require('firebase-admin');
admin.initializeApp();
admin.database().useEmulator('127.0.0.1', 5001);
uerden
  • 176
  • 1
  • 13
0

The only thing that worked for me was to manually set the firestore settings to localhost:

db.settings({
  host: 'localhost:8080',
  ssl: false
});

My full connecting code looks like this

const firebaseConfig = {
  //your config Data from your firebase app
};

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

var db = firebase.firestore();
db.settings({
  host: 'localhost:8080',
  ssl: false
});
Gesichtsfelsen
  • 59
  • 1
  • 1
  • 7