In short, I want to test a Firebase function locally, specifically one that is triggered from a realtime database trigger. According to the docs for local testing, it seems that there are two ways of accomplishing local testing of Firebase functions:
- Using the firebase functions emulator (
firebase emulators:start --only functions
) - Using the firebase functions shell (
firebase functions:shell
)
First, the differences between the two, at least in the linked guide, are very unclear. For the Firebase folks reading this, doc updates here would be great (considering local testing of this stuff is such an important feature).
My focus in this question (with respect to what I've tried) is based on the emulator, namely because it's mentioned that there are "interactions with other services". Interestingly, the list there only includes two items:
- Cloud Firestore
- Firebase Hosting
There is a notable omission of Realtime Database, and maybe that's where the gap is, but here we go.
My function looks something like this:
console.log("Hello World")
exports.myDatabaseTrigger = functions.database.ref('/a/path/{id}').onCreate((data, context) => {
console.log(`myDatabaseTrigger triggered - here's my path ${data.ref.path}`);
//manipulate some other stuff in the DB
})
In my project, I am using both Functions and Realtime Database, so I run the command firebase emulators:start
and it starts up both emulators.
In Postman, I use the local Realtime Database REST API to post some data with the following params:
POST
http://localhost:9000/a/path.json
{
"some": "data"
}
And I get back a response containing the name of the newly created item under /a/path
. However, my Firebase function never fires, and I never see the inner log (although the Hello World
log does print when the emulator starts).
So, is the interaction between these two emulators possible? Or, am I forced to use the functions shell? My issue with the shell is that, based on the realtime database examples, it's not clear what the DataSnapshot variables (i.e. data.ref.path
) will be if I simply call my function with some random value (e.g. myDatabaseTrigger({"some": "data"})
).