DEV Community

Cover image for Deploy Each NestJS Module as a Separate Firebase Function
Felipe Osano
Felipe Osano

Posted on • Edited on

2

Deploy Each NestJS Module as a Separate Firebase Function

Example and step by step guide: nestfire-example

When working with Firebase Functions, Firebase only gives us a folder to work in. There is no clear structure, no dependency injection, and no separate layers. This puts us at high risk of ending up with code that is hard to maintain and full of errors.

The solution is NestJS. With this framework we get a clear structure and all these problems are solved. It is used in large projects and has a strong community.

But how do we combine NestJS with Firebase Functions?

When we start a project with the command nest new projectName, NestJS creates the initial structure and a src folder where we can add our modules.

A module has a .module.ts file. One of the roles of this file is to define everything the module needs to run.

So, if a module includes all its dependencies, can we build and deploy it on its own to Google Cloud (Firebase Functions) or AWS Lambda? The answer is yes, but there are a few things to keep in mind.

  1. A module by itself is just code. If you drop it into Firebase Functions without the Nest server bootstrap, it won’t run because there’s no HTTP server process listening.
  2. You need a “main” entry file to start Nest, load the module, and expose its routes.
  3. Controllers inside the module only work if that entry file wires them up to an HTTP handler.
  4. Global providers (like APP_FILTER or APP_INTERCEPTOR) you’ve defined in your AppModule won’t automatically be included when you compile and deploy a single module — you have to re-apply them or import the same provider configuration in each module’s bootstrap.

The solution to all of this is NestFire.

NestFire

NPM: https://www.npmjs.com/package/nestfire

Image description

This npm package automatically solves all those problems.
All you have to do is:

  1. Install it in your project
  2. Configure it by adding an environment variable and updating your firebase.json
  3. Add the @FirebaseHttps() decorator to each module you want to deploy
  4. Run firebase deploy --only functions

Module example:

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { EnumFirebaseFunctionVersion, FirebaseHttps } from 'nestfire';

@FirebaseHttps(EnumFirebaseFunctionVersion.V2, { memory: '256MiB' })
@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {}
Enter fullscreen mode Exit fullscreen mode

This module will create a version 2 function (using Google Cloud Run) with 256 MiB of memory.

FirebaseHttps Decorator

This decorator adds the info passed as a parameter to the UserModule class. NestFire will use that info to know which Firebase Functions version to create and how to configure the function.

The decorator takes two parameters:

  1. The Firebase Functions version, using the EnumFirebaseFunctionVersion enum
  2. The function configuration: use RuntimeOptions for version 1 and HttpsOptions for version 2

Index.ts File

When NestFire is installed, it automatically creates an index.ts file in the project root.

index.ts:

import { AppModule } from 'src/app.module';
import { firebaseFunctionsHttpsDeployment } from 'nestfire';

export = firebaseFunctionsHttpsDeployment(AppModule);
Enter fullscreen mode Exit fullscreen mode

The function firebaseFunctionsHttpsDeployment(AppModule) takes the AppModule as a parameter.

When you run firebase deploy --only functions, Firebase uses the settings in your firebase.json. That setup needs to point at the index.ts file created by NestFire, so you must change the source to "source": "."

{
  "functions": [
    {
      "source": ".",
      "runtime": "nodejs22",
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

When we run firebase deploy --only functions, the firebaseFunctionsHttpsDeployment(AppModule) function in index.ts will execute. It goes through every module imported in AppModule and looks for the information added by the @FirebaseHttps decorator. When it finds a configured module, it adds the providers from AppModule, creates an Express server, and uses NestFactory.create to make a Nest application instance. It also saves that instance so it does not have to recreate it from scratch on cold start.

This way, all modules with the @FirebaseHttps() decorator will be deployed when you run firebase deploy --only functions. You can easily change their configuration and avoid a lot of problems.

The result is a regular NestJS backend, but we can deploy it separately on smaller, faster, and cheaper instances.

Example
Example and step by step guide: nestfire-example
NPM: https://www.npmjs.com/package/nestfire

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

Tiger Data image

🐯 🚀 Timescale is now TigerData: Building the Modern PostgreSQL for the Analytical and Agentic Era

We’ve quietly evolved from a time-series database into the modern PostgreSQL for today’s and tomorrow’s computing, built for performance, scale, and the agentic future.

So we’re changing our name: from Timescale to TigerData. Not to change who we are, but to reflect who we’ve become. TigerData is bold, fast, and built to power the next era of software.

Read more

👋 Kindness is contagious

Delve into this thought-provoking piece, celebrated by the DEV Community. Coders from every walk are invited to share their insights and strengthen our collective intelligence.

A heartfelt “thank you” can transform someone’s day—leave yours in the comments!

On DEV, knowledge sharing paves our journey and forges strong connections. Found this helpful? A simple thanks to the author means so much.

Get Started