What if we could deploy a backend application in just a few steps, without going through the overly complicated configuration process? Imagine doing so without worrying if it can keep up with incoming traffic and get all these domain certificates already on board. This is actually possible with Firebase Functions and any framework based on Express (including Express itself).
Firebase Functions is an alternative to AWS Lambda, created with ease of use and fast deployment in mind. According to official documentation, “Functions let you automatically run backend code in response to events triggered by Firebase features and HTTPS requests.” You can write any JS code and run it with a simple request or by setting up a trigger. What is more, Functions require exactly the same parameters as ExpressJS, meaning we can just forward anything through Functions, and let Express take care of it. This enables the use of the service as a deployment server for the whole backend application.
“NestJS is a framework for building efficient, scalable Node.js server-side applications.” Nest philosophy is to provide good architecture, regardless of the size of the project. Since its architecture was inspired by Angular, it takes advantage of most modern JavaScript and TypeScript practises. Under the hood, it uses either Express or Fastify. We can use this to our advantage, using Express from Nest as a Firebase Function.
Why?
The entire deployment process is very hard to set up right and fast using Kubernetes or Docker. If you are creating a small side project or a startup with little traffic, you want to cheaply set up deployment in minutes. Firebase Functions are (to some extent) free and do all the necessary stuff like load balancing and SSL out of the box. It’s a good match for such needs.
But why mix it with NestJS? Of course, you can simply create a small function to do the exact task you need, but sometimes a more organised structure with more possibilities is needed. NestJS is a good candidate when planning to write a microservice, but it’s also a great tool for a standard backend app.
Pre-setup
Before we begin to set up the whole application, there are some preparations we have to take care of:
- Download Firebase CLI – it will be needed for deployment and initial configuration
$ npm install -g firebase-tools - Create Firebase project (optionally) – this will come in handy when setting up Firebase Functions, because we can already select a project during this process. You can create a new project here: https://console.firebase.google.com. Projects can also be created with the firebase init command.
- Download Nestjs CLI – this step could be considered optional, but will massively speed things up, so I’ve decided to keep it. If you really don’t want this module, you can skip it and configure the nest project by yourself, or use some kind of boilerplate.
$ npm install -g @nestjs/cli
Setup
Now, once you are ready, go to the directory where you want your project to be stored. Please note that you don’t have to create a project directory – it will be created automatically in the 1st step.
- Create a Nest project as usual. I’ve chosen the standard way by executing:
$ nest new project-name
This will automatically generate directory, all startup files, configuration (including package.json) and initialize the Git version control system. - Login to Firebase:
$ firebase login - Go to project directory and initialize Firebase Functions:
$ firebase init functions
There will be 4 steps:
- Associating a project.
From there, you can select the project you created. This will be treated as the default project. This can be modified later if you want. - Choosing language.
Select TypeScript, as Nest use TypeScript. - Lint configuration.
It’s up to you whether you want the Firebase Tslint config, but because it’s deprecated, I don’t recommend it. Configure Eslint for your project on your own. - Installing dependencies with npm
I wouldn’t recommend doing it, because we will use package.json generated by Nest.
Modify package.json
Go to the functions directory and open package.json. We will copy part of this file to package.json in the project directory.
Copy scripts
If you are using yarn, you should also change all npm run -> yarn
Setup Node version
Firebase supports Node 8 and Node 10 (still Beta when writing this article). Node 8 is what was generated by Firebase, so I left it as is.
Copy the necessary dependencies
Setup main
The file should look like this:
Remove the functions directory, as it is not needed anymore
Modify firebase.json
We need to tell Firebase where to look for functions. Firebase is looking for the index file in the specified directory. Since firebase.json is in the same directory as the Nest application, we can just add:
Important! This should be added inside the functions property.
The whole file should look like this:
Run package installation
Create the index file as an entry point
The file should be located in the same directory as the source of firebase.json.
The essential thing is whatever you name that exported variable, that will be the name of the function in Firebase Functions. I called mine api, so the entry point to my application will be {FIREBASE_ADRESS}/api.
Another critical thing is that if you don’t specify a region, it’s set by default to us-central1.
OK, that’s it for now, I hope you like this article, and you’ll find it useful! Cheers!