Build Webhooks with Serverless Google Firebase Cloud Functions (Sample App) July 2022 · ian
Introduction
Here at HostedHooks we are always looking for cool ways to integrate Webhooks and this topic is one that we were very excited to work on. There is a good chance that you have heard the term "Serverless". It is a realtively new option in the software development world that allows developers to offload some of their application's workload to the cloud and in a way that doesn't require managing servers. Due to the ease and simplicity, serverless is becoming increasingly popular. So much so that all of the major cloud providers (AWS, Google Cloud, Azure) have their own flavor of serverless. In this post we will specifically focus on Google's version which is the Firebase product and show you how to integrate HostedHooks into Cloud Functions for Firebase (Google).
In this demo we will be building the Cloud functions using Node.js, but Firebase Cloud Functions supports a few other languages, so even if you are not a Javascript developer this post will still be applicable to you from a structure and design perspective. In this example we'll be building a Google cloud function that listens for inserts in the Users table and will send a webhook message whenever that occurs. This app could showcase the flow for sending welcome emails to new users or maybe transactional emails based on some new input into the database. This same flow would work for any process that needs to be kicked off based on the triggering of a new event, there are many possibilities.
To summarize, we are going to be building an app that will simulate what happens when a new user has been added to our database. Once that occurs the function will trigger a webhook event ( via HostedHooks ) and will send out a 'user.created' webhook event to the subscribed webhook users. The app is fully open sourced (see the resources below) so you can clone the code and run it locally alongside this demo.
We hope you enjoy it and let us know if you have any questions or feedback!
Getting Started
Resources
Here are some additional resources that you may need before we get started:
- Firebase Functions Webhooks Sample App Github Repo
- HostedHooks Dashboard
- HostedHooks Platform Setup
- Google Cloud Functions for Firebase
To integrate the Node.js demo app with the HostedHooks webhook service you will need to start by creating a HostedHooks account. It will only take a few minutes and then we can get started on the fun part.
Step 1: Create an account
Go to www.hostedhooks.com/sign_up to create an account and fill in your organization info, it will take a few minutes.
Step 2: Generate an app for your webhooks
Next, you need to create a new app, this app is where your webhooks will be sent from, just click on "Setup new app" in your dashboard and enter the app name, you can call it "Firebase App".
For more info, check our documentation.
Step 3. Create a Webhook Event for your app instance
After creating your app, it's the time to prepare our app to recieve webhooks, let's create a Webhook Event that subscribers can subscribe to.
In our Firebase App, we create a user.created
event, that should be triggered whenever a new user is written in the database.
Here are some additional events that you may create for this Firebase App (but we won't cover these here):
user.updated
- triggers whenever a user is updated.user.deleted
- triggers whenever a user is deleted.
We recommend you follow a convention when naming your events, something like namespace.event
would work.
Note: The event name being sent from your application must match the event name of the webhook event created in your app instance and the webhook events must be created first.
For more info, you can review our documentation.
Setup Firebase
1. Signup and Install Firebase CLI
First you need to create a firebase project, you can do so by heading here. Once you have an account you need to install the Firebase CLI to manage and deploy your Firebase projects.
npm install -g firebase-tools
That makes the firebase
command global. For more information, checkout the documentation
2. Log in and test the Firebase CLI
After installing the CLI, you must authenticate. Then you can confirm authentication by listing your Firebase projects.
firebase login
This command connects your local machine to Firebase and grants you access to your Firebase projects. For more information, checkout the documentation
Preparing the app
Now that we are setup, let's move onto the code. You can clone our ready-to-go app and follow along with us.
First we will set up our environemnt variables.
Inside firebase functions
folder in the root directory, copy the .env.example
file to .env
(which will be ignored by Git):
cd functions
cp .env.example .env
Then set each variable in the .env
file :
HOSTEDHOOKS_API_KEY
must be the API Key from your account settings.APP_UUID
must be the ID of your HostedHooks app instance.
Your .env
file should look like this:
HOSTEDHOOKS_API_KEY=...
APP_UUID=...
Within the same folder, run npm install
to install the dependencies:
npm install
Set the event handler:
Firebase Cloud Functions supports event handlers for Realtime Database events, you can listen for creation, update and deletion events or any change at all. Check out the full details here.
In our demo app, we will be listening for the creation event and we do this by specifying the path of the instance that we want to listen to, users
in this case.
Whenever a new user is added to the users
instance, the onCreate()
function fires. This takes a callback with the snapshot
and context
parameter. The snapshot
parameter contains the data that was written to the database and the context
parameter contains the params and authentication information. For more details, checkout Firebase documentation
Within the onCreate()
function, we are taking the data received from the Firebase event and passing it into a sendWebhookMessage
function which will kick off the API call to HostedHooks.
// index.js
const functions = require("firebase-functions");
const { sendWebhookMessage } = require("./utils/webhooks");
exports.callHostedHooks = functions.database
.ref("/users/{userId}")
.onCreate((snapshot, context) => {
// getting the newly created user data
const createdUser = snapshot.val();
console.log(createdUser);
// getting the user ID
const userId = context.params.userId
console.log(userId);
// sending webhook message
return sendWebhookMessage("user.created", createdUser);
});
Building your webhook message:
Here we show the internals of the sendWebhookMessage
function which is taking all of the firebase data and building the API call to send the Webhook Message to HostedHooks.
We start with the url
which is the API endpoint that you will be sending the event data to. In this case it only requires the APP_UUID
that we setup earlier in the .env
file. You will want to dynamically add that into the endpoint URL. If this were a production platform we would recommend that you not store the APP_UUID
in the env var, but for the sake of simplicity it's ok here.
Once you have the url next is the payload of the webhook message:
data
: It is your custom payload and the information that will be passed on to your webhook subscribersversion
: This is the version of the payload that you want to send. You can build different versions of your payloads without breaking your existing subscribers integrations.event_type
: This is the webhook event that was triggered. It is the attribute that we use to route your webhook to the correct subscribers.
Once all of that is setup you are ready to start testing end to end.
// ./utils/webhooks
const axios = require("axios");
exports.sendWebhookMessage = async (event, userData) => {
var url = `https://www.hostedhooks.com/api/v1/apps/${process.env.APP_UUID}/messages`
// webhook message
var messagePayload = {
data: {
user: userData, // user data
},
version: "1.0",
event_type: event, // ex: 'user.created'
};
var requestOptions = {
headers: {
Authorization: `Bearer ${process.env.HOSTEDHOOKS_API_KEY}`,
"Content-Type": "application/json",
},
};
try {
const response = await axios.post(url, messagePayload, requestOptions);
console.log(response.data);
} catch (error) {
console.error(error);
}
};
Triggering the function
Now you are all set to create a new user. Head into your console and click the "All Products" link on the sidebar, that will bring you to a view like the below. Click on "Realtime Database" and that will take you to your users database where you can add records.
Once in the Realtime Database view, hover over users
and click the +
button that appears. In the fields that show up, add random data to emulate adding a new user to the users
collection.
Once the record gets added to the database, our code listening for events will get triggered and a webhook message will be sent to Hostedhooks.
You can see this by jumping back in to your HostedHooks dashboard, where you will see the message that we sent has been recieved.
Add Subscribers
Lastly, to show the full flow, we will need to setup a subscriber to receive the webhook data. The step above made an API call to HostedHooks letting the platform know that data has changed, but now we need to route that new event data to a webhook subscriber. In our example a subscriber might be a user of your application that wants to know whenever a new user signs up.
We've covered how to setup a subscriber in another article which is linked here here. Please follow along there and come back here once ready.
Once your subscriber is setup and subecribed to the user.created
event, we can rerun the previous step by manually entering a new user and we'll see the webhook flow end to end.
The flow: Manually creating a user on our firebase database -> HostedHooks -> Subscriber endpoint
This gif is showing us manually creating a user on our firebase database, then sending that event over to the HostedHooks API, routing to the subscriber that we created.
Recap
To recap, we've just walked through how simple it is to setup Google Firebase serverless cloud functions to listen for database updates and send out webhooks. We hope this was helpful and if you have any questions, please reach out!
Follow Us
You can follow us @hostedhooks or sign up below to receive our updates.
Try HostedHooks Free
Getting started is easy! No credit card required.