Serving NestJS via Firebase Functions
Intro
This is a simple step-by-step guide/note of how to deploy NestJS in Firebase Functions to go serverless as of September 2021. What I am writing here is almost entirely from the following link of Fireship.io.
It is an incredible source but I had to write this post (1) because I am amateur developer and I need a more digestible details, and (2) I wanted to record some of the changes I made after a few failed tries.
Details
I chose Option A of 'Point a function to Nest' from the site. It seemed to make NestJS and Firebase more decoupled than Option B of 'Add Nest to the Functions Source'.
Prerequisites:
- You need to set up your project for 'Pay-as-you-go' tier in Firebase to use Functions. It is a good idea to set up your Firebase project before Step 0.
Step 0: Install Firebase tools and NestJS
You need both Firebase tools and NestJS installed on your machine.
$ npm i -g firebase-tools && npm i -g @nestjs/cli
Step 1: Create a folder for Firebase Functions.
Note the directory structure:
- The parent directory has
firebase.json
and.firebaserc
files, and a NestJS project directory is laid as its child.$ mkdir my_functions_project && cd my_functions_project
- Inside the newly created
my_functions_project
directory, initialize for firebase functions.$ firebase init functions
- You will need
functions
directory within the NestJS project directory (not immediately inmy_functions_project
), so you can delete thefunctions
directory now.$ rm -rf functions
Step2: Adjust firebase.json to the NestJS directory
- Inside the
firebase.json
file, add the line of"source": "my_nestjs_project"
underfunctions
."functions": { "predeploy": "npm --prefix \"$RESOURCE_DIR\" run build", "source": "my_nestjs_project" } }
Step3: Create a NestJS project.
- Inside
my_functions_project
directory, type in the following command:$ nest new my_nestjs_project
Step 4: Add Firebase and Express in NestJS Project.
- We need Firebase Functions and Firebase Admin in our NestJS project directory.
- We also need to install Express and its adaptor for NestJS, so run the following commands: (I broke lines for improved readability.)
$ npm i firebase-functions firebase-admin $ npm i express @nestjs/platform-express
Step 5: Create main.firebase-functions.ts in the NestJS project
- In
my_functions_project/my_nestjs_project/src
, createmain.firebase-functions.ts
with the following content. - N.B. Yes, this is in addition to your
main.ts
. DO NOT DELETE IT.
import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import { AppModule } from './app.module';
import * as express from 'express';
import * as functions from 'firebase-functions';
const server = express();
export const createNestServer = async (expressInstance) => {
const app = await NestFactory.create(
AppModule,
new ExpressAdapter(expressInstance),
);
return app.init();
};
createNestServer(server)
.then((v) => console.log('Nest Ready'))
.catch((err) => console.error('Nest broken', err));
export const api =
functions.region('asia-northeast3').https.onRequest(server);
- Note that I used
asia-northeast3
for region, but you can choose one that you may find more suitable. Visit this link for a list of available regions..
Step 6: Edit eslintrc.js
to make eslint happier.
- VSCode can give an annoying error that
import
is wrong. This can be corrected by changingparserOptions.project
fromtsconfig.json
tomy_nestjs_project/tsconfig.json
.
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'my_nestjs_project/tsconfig.json',
sourceType: 'module',
},
Step 7: Update package.json
of your NestJS project.
- You need to add the following lines at the top level of
package.json
."main": "dist/main.firebase-functions.js", "engines": { "node": "14" },
- I have also added the following lines for convenience.
"scripts":{ ... "serve:firebase": "nest build && firebase serve --only functions", "deploy:firebase": "nest build && firebase deploy --only functions", ... }
Step 8: Test to see if it works.
In the my_functions_project/my_nestjs_project
, run the following commands to see if everything works:
$ npm run serve:firebase
$ npm run deploy:firebase
$ npm run start:dev
Conclusion
I wrote this post as a note to myself but for others who may benefit from it. Leave your comments and/or questions how you like it.
Versions info (as of Sept 19, 2021)
- Firebase: 9.18.0
- NestJS: 8.1.1
- NodeJS: 14.17.5