Firebase emulators blocking firebase functions? - firebase

So in my web app, I am calling an https callable cloud function like so
const createStripeCheckout = functions.httpsCallable('createStripeCheckout')
//Call function
And up until I started using the firebase emulator, everything was fine. It was making a request to the https endpoint, and the checkout was made successfully. But after I used functions in the emulator, it makes a request to the local dev server (localhost:5000/firebase-project/name) instead of the correct https endpoint hosted by firebase (firebase/name) and the function can't work unless I start the emulator, and will only work on my computer. I don't recall changing any settings.

Found the problem, in my code there was a line that read:
functions.useEmulators("localhost", 5001)
I guess that directed all functions to that adress

Related

Localhost Firebase Cloud Functions are working with the emulator but not live

I have a Firebase app with an App Check debug token implemented.
When I run my Cloud Functions using the Emulator they work fine.
But when I turn off the emulator and try to access the live deployed version from http://localhost:8080/ I get this console error:
POST http://localhost:5001/my-app/us-central1/getZohoDeskTicketsLoggedInUser net::ERR_CONNECTION_REFUSED
Why does this happen when calling the live version and not with the emulator?
There are no Firebase Cloud Function logs to provide because the functions never even fire.
Perhaps I need to white list the locahost domain somewhere?
When you deploy your web app to productions, you should use URL of deployed Cloud function to make your API requests instead of localhost which will lead to connection errors. You can additionally call connectFunctionsEmulator only when you are on localhost:
if (window.location.hostname === "localhost") {
connectFunctionsEmulator(...)
}

Can I deploy a Firebase https callable (.onCall) using Terraform?

So AFAIK, all triggered cloud functions can essentially be deployed using google deploy command which in turn allows me to deploy through terraform through similar parametrization. That being said, I can't seem to deploy a https callable function with:
event_trigger {
event_type = "https.onCall"
resource = ""
}
My assumption is that it's because https callables are explicitly a firebase only "system".
Has anyone gone through this kind of situation before?
Firebase's callable functions are just HTTPS functions that follow a special protocol. The function-side wrapper around that is provided by the firebase-functions SDK and deployed only by the Firebase CLI. If you can't use the Firebase CLI, you're going to have a hard time coming up with an equivalent way to deploy that code. It might be easier to just code your own protocol on both the client and function and deploy with the tools that are compatible with your deployment process.

Firebase: how to debug onCall functions?

I am using Google Cloud Functions Emulator for debugging locally my Firebase functions.
Firebase recommend to use functions.https.onCall functions instead of functions.https.onRequest for avoid using http calls directly. Instead Firebase recommend to use Firebase Functions SDK for call such functions from code.
For functions.https.onRequest I used http-trigger flag but how can I debug onCall functions ?
I found a way to run 'onCall' cloud functions locally and call them from a local client. I still haven't figured out how to attach a debugger but at least I can iterate faster and use console.log statements.
Use firebase serve to host the functions. Even though these are supposed to be for http requests I found that the the firebase clients have a property to override the host name for onCall functions. This takes care of authentication and passing in the right data and context objects for you.
From Terminal in the root of your firebase project folder:
firebase serve
You should get a successful result in the terminal window. Take the hostname and port number:
✔ functions: helloWorld: http://localhost:5000/your-project-name/us-central1/helloWorld
iOS client:
Functions.functions().useFunctionsEmulator(origin: "http://localhost:5000")
NOTE: you have to disable App Transport Security in iOS for this to work
NOTE: other clients probably have the same API.

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.
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')
}
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) => ...)

Prevent firestore triggers when serving firebase functions locally

I am new to Firebase, I setup a project and using nodejs + nestjs
I have a https trigger function that adds record to Firestore
I have a Firestore document onCreate trigger, to duplicate data to another collection
Then I try to run Firebase locally by running npm run serve which is calling firebase serve --only functions
Then I can access the https function via postman app.
First problem is Firestore onCreate trigger is not fired locally when I call my local https function.
Second problem is Firestore onCreate trigger is run on server and I can see running logs, which means in development time, some buggy bad code could be running on server and that code might corrupt data (while the good code is under development and bugs are fixing on my local)
So my question is, how usually people do development on their local and testing?
firebase serve --only functions only emulates HTTPS functions.
firebase experimental:functions:shell works with everything else, but you have to construct stub data to send to it.
See the documentation for more information:
Run Functions Locally
Unit testing functions

Resources