Organize Your Firebase Functions For Easier Deployments and Maintenance
When developing Firebase functions, it's common to have everything in a single repository - all the Firebase Functions for your project. This is usually fine when you are starting out.
When developing Firebase functions, it's common to have everything in a single repository - all the Firebase Functions for your project. This is usually fine when you are starting out.
But as your project grows, this can start to have negative impacts, for instance, slow deployment as Firebase has to build large functions, upload and figure out what changed and didn't change.
On top of that, it also makes it very difficult for multiple teams to work on the same project, making it hard to deploy and maintain as teams work on their features.
Firebase Functions Codebases
So, how do you manage this? Firebase provides the concept of Firebase Functions Codebases, where Firebase functions can be organised into a collection in a way that makes sense to an organisation, say a team owns them or by feature, and maintained and deployed together.
The functions collections can be in different repositories or the same repository in a mono-repo setup using something like NX in combination with the NX generator for Firebase that I built earlier this year.
Firebase codebase allows you to organise your Firebase functions collection in a way that makes sense to your organisation. This could be by functionality or teams and so, allowing you to maintain and deploy them together.
By default, firebase has a single default codebase, and your Firebase config file - firebase.json
- it looks like this.
{
// ... other firebase services configurations i.e. hosting etc.
"functions": [
{
"source": "dist/apps/functions",
// default codebase
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
],
"predeploy": [
"pnpm nx run functions:build"
]
}
],
"extensions": {}
}
We can configure a different codebase for our Firebase functions for a second collection of functions by modifying the codebase property of one of our functions.
For instance, in the above example, we can add a second functions collection with a different codebase by adding a second config option to the functions property inside our firebase.json
config file.
{
// ... other firebase services configs
"functions": [
{
"source": "dist/apps/functions",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
],
"predeploy": [
"pnpm nx run functions:build"
]
},
{
"source": "dist/apps/functions",
"codebase": "codebase-2",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
],
"predeploy": [
"pnpm nx run functions:build"
]
}
]
}
In the case above, our different functions collections exist in the same repository - a mono-repo. We could have our functions collection exist in multiple repositories. In such cases, we would just need the only codebase inside the repository to be configured in our firebase.json
config file.
{
// ... other firebase services configs
"functions": [
{
"source": "dist/apps/functions",
"codebase": "codebase-2",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
],
"predeploy": [
"pnpm nx run functions:build"
]
}
]
}
NB: Ensure that the codebase property is correct, as this could have unforeseen consequences, such as deleting other functions in the codebase that weren't found inside the repository.
Deploying your Functions
As always, firebase deploy
and Firebase deploy functions will deploy all Firebase functions within the current directory
in all codebases. On top of that, you can specify which codebase to deploy by using the firebase deploy functions:codebase
command.
firebase deploy functions:codebase
If your function collections are distributed in multiple repos, you can just use the firebase deploy
command. Firebase CLI will not prompt you to delete existing Firebase function collections from other codebases.
But suppose your function collections are in a mono repo setup. In that case, you might find it beneficial to have your target to a specific codebase instead of deploying all codebases within the mono repo.
firebase deploy functions:codebase
Firebase Functions NX Generator
For those of you using NX or want to use NX to manage your Firebase project, you might find it beneficial to try out the generator I created to create Firebase functions as NX apps, with full support for codebase - @nx-toolkits/firebase.
Each Firebase functions codebase lives as an NX application, with all the benefits of NX, such as codesharing between codebases and caching. For more information, check out this post about my motivations as to why I built the generator.
How it works
First, install the @nx-toolkits/firebase generator using your favourite package manager.
// npm
npm i @nx-toolkits/firebase
// yarn
yarn add @nx-toolkits/firebase
//pnpm
pnpm add @nx-toolkits/firebase
To generate a function in the default codebase, just run the following command:
nx g @nx-toolkits/firebase:functions
NB: Please ensure that you have run Firebase initialisation in the root directory of your project. In the future, I would like to be able to handle this as well.
This will create or override the default codebase application. To create an NX application with a different codebase, just run the following command:
nx g @nx-toolkits/firebase:functions --codebase codebase-2
And that's it. Running the nx deploy
command targeting the app you just generated will only deploy functions of the correct codebase.
nx run my-functions-app:deploy
And that's it.
Conclusion
In this post, we looked at how we can use codebases in Firebase functions to organise our Firebase functions, making it easy to maintain and deploy as our app grows.
It's important for any project to be able to enhance effectiveness and ensure different features can be developed and maintained with minimal conflicts and speed.
Codebases make it easy for organisations to decide how to organise Firebase functions as it makes sense to them, be it in a mono repo setup or even multiple repositories, so as to achieve business goals.