Reputation: 967
I can't seem to find the solution for this in the Firebase Documentation.
I want to test my functions.https.onCall
functions locally. Is it possible using the shell or somehow connect my client (firebase SDK enabled) to the local server?
I want to avoid having to deploy every time just to test a change to my onCall
functions.
Function :
exports.myFunction = functions.https.onCall((data, context) => {
// Do something
});
Client:
const message = { message: 'Hello.' };
firebase.functions().httpsCallable('myFunction')(message)
.then(result => {
// Do something //
})
.catch(error => {
// Error handler //
});
Upvotes: 44
Views: 21201
Reputation: 530
For anyone coming here on 2023/2024, now you need to use useEmulator
function (react native example)
if (__DEV__) {
firebase.functions().useEmulator("localhost", 5001);
}
const myFunctionCall = functions().httpsCallable("FUNC_NAME");
const result = await myFunctionCall(MY_DATA_TO_BE_SENT);
Upvotes: 0
Reputation: 3966
There's a function attached to the HTTPSCallable function called run
that:
"Executes the handler function with the provided data as input. Used for unit testing".
You can simply do this:
test("something", async () =>
{
const res = await myCallableFunction.run({
data: {
// arguments
},
auth: { // optional
uid: "test-user",
token: { email: "test-email" } as any,
},
rawRequest: {} as any,
});
});
Upvotes: 1
Reputation: 2692
There is a simple trick, how you can simplify onCall
-function testing. Just declare the onCall function callback as a local function and test that instead:
export const _myFunction = (data, context) => { // <= call this on your unit tests
// Do something
}
exports.myFunction = functions.https.onCall(_myFunction);
Now you can variate all cases with a normal function with the input you define on your function call.
Upvotes: 8
Reputation: 49600
you should first check for dev environment and then point your functions to local emulator.
For JS:
//after firebase init
if (window.location.host.includes("localhost") ||
window.location.host.includes("127.0.0.1")
) {
firebase
.app()
.functions() //add location here also if you're mentioning location while invoking function()
.useFunctionsEmulator("http://localhost:5001");
}
or if you don't create instance of firebase then
//after firebase init
if (window.location.host.includes("localhost") ||
window.location.host.includes("127.0.0.1")
) {
firebase
.functions()
.useFunctionsEmulator("http://localhost:5001");
}
or when serving pages from backend (node.js):
//after firebase init
if (process.env.NODE_ENV === 'development') {
firebase.functions().useFunctionsEmulator('http://localhost:5001');
}
Upvotes: 2
Reputation: 9186
if you are using angularfire, add this to you app.module
{
provide: FirestoreSettingsToken,
useValue: environment.production
? undefined
: {
host: "localhost:5002",
ssl: false
}
}
Upvotes: 0
Reputation: 6648
Although the official Firebase Cloud Function docs have not yet been updated, you can now use firebase-functions-test with onCall
functions.
You can see an example in their repository.
I have managed to test my TypeScript functions using jest, here is a brief example. There are some peculiarities here, like import order, so make sure to read the docs :-)
/* functions/src/test/index.test.js */
/* dependencies: Jest and jest-ts */
const admin = require("firebase-admin");
jest.mock("firebase-admin");
admin.initializeApp = jest.fn(); // stub the init (see docs)
const fft = require("firebase-functions-test")();
import * as funcs from "../index";
// myFunc is an https.onCall function
describe("test myFunc", () => {
// helper function so I can easily test different context/auth scenarios
const getContext = (uid = "test-uid", email_verified = true) => ({
auth: {
uid,
token: {
firebase: {
email_verified
}
}
}
});
const wrapped = fft.wrap(funcs.myFunc);
test("returns data on success", async () => {
const result = await wrapped(null, getContext());
expect(result).toBeTruthy();
});
test("throws when no Auth context", async () => {
await expect(wrapped(null, { auth: null })).rejects.toThrow(
"No authentication context."
);
});
});
Upvotes: 8
Reputation: 686
For locally you must call (after firebase.initializeApp)
firebase.functions().useFunctionsEmulator('http://localhost:5000')
Upvotes: 65
Reputation: 317828
Callables are just HTTPS functions with a specific format. You can test just like a HTTPS function, except you have to write code to deliver it the protocol as defined in the documentation.
Upvotes: 6