Nx Nrwl Firebase Functions
Since Nrwl released its support for node applications I was looking forward to similar support for Firebase Functions. I have even created an issue on GitHub for that. At the time of writing it is still open, that’s why I have decided to create my own solution.
The problem
When you initialise Firebase Functions withfirebase init
it creates functions subdirectory with its own package.json
and node_modules
. That is not good. We want to share code with functions and manage it using Nx.
Goal
- Firebase Functions exist as a node app
- There is only one
package.json
andnode_modules
- Functions can use shared code from
libs
Prerequisites
We assume you have a working Nrwl Project with Angular application. It is also recommended that you have Firebase account and understand what Firebase Functions are.
Solution
Setup Firebase
If you haven’t already, install firebase-tools
and login:
yarn global add firebase-tools
firebase login
Also add .firebaserc
in the root dir to make it a Firebase project:
{
"projects": {
"default": "your-firebase-project-name"
}
}
Generate node-app
As stated in goal, Functions are to be based on node-app
. To do so, create node-app
named “functions”:
ng add @nrwl/node # Adds Node capabilities
ng g @nrwl/node:application functions
Configure Firebase Functions
Install Firebase Functions dependencies
yarn add firebase firebase-admin firebase-functions
Replace contents of apps/functions/src/main.ts
with:
import * as functions from 'firebase-functions';
// // Start writing Firebase Functions
// // https://firebase.google.com/docs/functions/typescript
//
export const helloWorld = functions.https.onRequest((request, response) => {
response.send('Hello from Firebase!');
});
Above snippet is what Firebase generates when using firebase init
.
To setup Firebase Functions so that they are understood create firebase.json
in the root directory:
{
"functions": {
"predeploy": [
"yarn lint functions",
"yarn build functions --prod"
],
"source": "/"
}
}
predeploy
just defines what is fired when you issue commandfirebase deploy --only functions
. In this case it will run linter and production build for our “functions” project.source
points to the root of the project. Since we have only onepackage.json
and it is in the root directory it needs to point there.
In package.json
add following:
"main": "dist/apps/functions/main.js",
"engines": {
"node": "10"
},
main
is required so that Firebase knows what to start after deployment. I have created a feature request to move it tofirebase.json
but at the time of writing it needs to be there.engine
is telling Firebase on which node version it should be run. At the time of writingnode v10
is the newest supported. Also you CANNOT specifyyarn
ornpm
version in here because it will conflict with firebase.
Usage
Serving Firebase Functions is a little more complicated than typical node app. Add this dev dependancy:
yarn add concurrently -D
And these scripts to package.json
:
"firebase:serve": "concurrently --kill-others \"yarn run build functions --watch\" \"firebase serve --only functions\"",
"firebase:shell": "concurrently --kill-others \"yarn run build functions --watch\" \"firebase functions:shell\" --raw",
"firebase:deploy": "firebase deploy",
yarn firebase:serve
- run functions locallyyarn firebase:shell
- run functions shell locallyyarn firebase:deploy --only functions
- deploy functions
Explanation
At the time of writing firebase serve
serves functions only from dist
directory. To make it work we use concurrently
to run build
with watch
flag, and serve
“concurrently”.
Summary
This pretty much covers it. Easy and elegant way to incorporate Firebase Functions into Nx project. Source code for this can be found in here. However it is actively developed so if you want to review THIS version, checkout this commit.