Prevent firestore triggers when serving firebase functions locally - firebase

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

Related

Which is the most optimal base url for functions fetch calls?

Background: Some days ago, Firebase Hosting added support for NextJS.
I have Firebase Functions and Firebase Hosting inside the same project.
I'm implementing an SSR with NextJS in Firebase Hosting, and now I need to run some fetch calls inside getServerSideProps. Those fetch calls will hit my own Firebase Functions, and I wonder if there is a better base-URL for making "local fetch" while getting that data. Some base-URL to tell Firebase Hosting: "Hey, this is a call to a resource that is inside Google".
My goal is to reduce the response time, while reducing the "tracert" stack.
In other words, I need a "local URL" to point locally in the Google-Firebase-Functions-Servers.

Run firebase functions emulator on database without database emulator (towards production cloud instead)

I am having trouble running the firebase functions emulator towards a production database. I have a project which is not publicly released yet so I can run towards production with any negative effects.
My project uses only the realtime database, it does not use Firestore (so other questions on SO are not relevant) The documentation states "Cloud Firestore and Realtime Database triggers already have sufficient credentials, and do not require additional setup." so according to that, I shouldn't need any additional setup in order to point to the production database.
According to all of the documentation on Firebase, the project should run towards the real firebase database if I only start the functions emulator and do not start the database emulator. This warning seems to say so, too:
functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: auth, firestore, database, hosting, pubsub
However, this is not what happens. Instead, I get the following error:
functions[onGlobalClientRequest]: function ignored because the database emulator does not exist or is not running.
I have read the firebase documentation and nothing is really mentioned other than setting credentials should not be needed (but I am setting credentials anyway using export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json" before running the functions emulator.)
onGlobalClientRequest looks like this:
export const onGlobalClientRequest = functions.database
.ref( client_requests_key + "/{pushedid}")
.onCreate(
async (
snap: functions.database.DataSnapshot,
context: functions.EventContext,
) => {
///.... code here...
},
);
The locally emulated Firebase Functions will be able to write to the Prod database, but will not be able to get triggered by the production database.
Here is a SO answer from a Google employee that states the aforementioned.
Also, quoting from this other SO answer from another Google employee:
In general the rule with emulators:start is that we comprehensively emulate whatever is running. So for example if you're running the Functions and Database emulator, all writes from functions (through admin.database().... will be redirected to the Database emulator. But writes to Firestore (admin.firestore()...) will try and hit production because that emulator is not running.
Operations on a Realtime Database (RTDB) trigger the functions in the corresponding project. So the production RTDB triggers functions of your production project, and the emulated RTDB triggers emulated functions.
If you want to test functions triggered by RTDB operations locally with the emulator, you have to use the RTDB emulator as well. This is explained in the doc here.
If you only want to test HTTP callable functions, then you can use a remote RTDB.

How to run firebase emulators for local development with functions, triggers on remote db?

I'm building a firebase API with cloud functions and want to reach my production Database for local testing.
My problem :
When I launch my two firebase emulator (functions and firestore) with
firebase emulators:start
1- My custom API endpoints run on http://localhost:5001 (this works)
2- My triggers reaches a local dababase on http://localhost:8080 whereas I didn't set FIRESTORE_EMULATOR_HOST=localhost:8080 (I want to reach my production database)
OR
When I launch only my "functions emulator" with
firebase emulators:start --only function
...but my triggers are not reached, probably because of this warning
i functions[userOnCreate]: function ignored because the firestore emulator does not exist or is not running.
On the other side I'm building a reactjs App also with firebase running on localhost:3000
I call my local API from this app with firebase SDK. To reach my emulator, I add the line :
firebase.functions.useFunctionsEmulator('http://localhost:5001');
The local emulators don't work with actual cloud-hosted instances of databases. Everything must be local.
You are always free to file a feature request.
you have to use firebase serve instead for firebase emulators:start

Unable to trigger firestore changes locally

I just started doing firebase and I need to do something when a new document is created but in functions and I setup cli and started locally but the function is not triggered.
while doing firebase init I chose firestore,functions,storage
after that did firebase login and firebase serve --only functions
and the server is up but whenever I add new document the function is not getting triggered?
You should be able to do that with firebase emulators:start. This starts emulators for Cloud Functions, Cloud Firestore, Realtime Database and Firebase Hosting. If that doesn't work, please share your code and I can have a look.
The docs may be useful too: https://firebase.google.com/docs/functions/local-emulator#run_the_emulator_suite

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.

Resources