DEV Community

Bernardo Cassina
Bernardo Cassina

Posted on

6

Firebase Functions Express Typescript Project Guide Part 1

This guide will walk you through setting up your Mac for development with Node.js, Firebase, and Firestore, including creating a simple Express app within a Firebase Functions project.

Prerequisites

  • Basic command line knowledge
  • Mac computer with admin access
  • Mac with XCode installed
  • Postman Installed
  • Create a Firebase Project before hand

Setup

0. Create a Firebase Project

  • Login into your google account
  • Go to the Firebase Console
  • Create a new project and name it however you like, we’ll use the name my-project for this example.
  • Don’t set Google Analytics, not necessary
  • After your Project is ready, you’ll be redirected to the project overview page
  • On the left Sidenav, click the settings icon, select Project settings
  • Look for your Project ID
  • Now go to the Firestore page here
  • Select the default location
  • Select Start in test mode
  • After the DB has been created, you’ll see an empty Database 😬
  • That’s all we need to know now, well come back to the console later

1. Install Homebrew and Java

  • Homebrew is a package manager for macOS. It simplifies the installation of software on macOS.
  • After installation, verify it by running:

    brew --version
    
  • Tu use the Firebase Emulators, we need to install the Java JDK, you can do it with homebrew, although there are other methods.

2. Install Node.js 18 Using nvm

  • Install Guide
  • Note: the example is for Node 16 although you should install Node 18 nvm, although with nvm you can have multiple node versions and choose between them πŸ˜‰
  • nvm allows you to manage multiple installations of Node.js.
  • After installing nvm and Node 18 , verify installation by running:

    node --version
    

3. Make sure npm is installed

  • Verify by running:

    npm --version
    

4. Install Firebase CLI

  • The firebase CLI is…
  • Install it globally by runnning:

    npm install -g firebase-tools
    
    
  • Verify the installation:

    firebase --version
    

5. Create a New Firebase Functions TypeScript Project

  • To use Firebase products like Functions, Firestore, Auth, and others, we need to create a new Firebase project.
  • Note: this project is different from your Firebase Console Project where we will deploy this Typescript project. To be clear: one is the code project and the other, a container in Firebase Console to deploy our code project.
  • Initialize your project:

    # In a terminal, change to your existing Develop directory:
    cd my-dev-directory
    # Create a new directory to store the project
    mkdir my-firebase-project
    # Move into the new directory
    cd my-firebase-project
    # Login into Firebase
    firebase login
    
    
  • That command will prompt a URL or open your browser so you can login with your google account.

  • After successful login, Initialize the Firebase project

    # Initialize Firebase
    firebase init
    
  • This will prompt different Firebase features to start the project, read the instructions thoroughly and then choose these options:

    • Select to use Firestore
    • Select to use Functions
    • Select to use Emulators
    • Leave all others features disabled
    • When prompted to select a project, choose the one you first created from the list
    • When prompted, select all defaults for the Firestore Setup
    • For the Functions Setup
    • Select TypeScript when prompted
    • Choose to use ESLint when prompted
    • Choose to install dependencies with npm, this will run npm install in the project and create the node_modules directory
    • For the Emulators Setup choose the Functions and Firestore emulators
    • Leave all defaults for the next options
    • Choose to download the emulators now ( this is what you need the Java SDK for)
    • Verify your project directory running:

      ls -la
      # The output should look like this
      total 40
      drwxr-xr-x   8   staff   256 May 13 15:33 .
      drwxr-xr-x   7   staff   224 May 13 15:07 ..
      -rw-r--r--   1   staff    68 May 13 15:33 .firebaserc
      -rw-r--r--   1   staff  1166 May 13 15:33 .gitignore
      -rw-r--r--   1   staff   650 May 13 15:33 firebase.json
      -rw-r--r--   1   staff    44 May 13 15:31 firestore.indexes.json
      -rw-r--r--   1   staff   755 May 13 15:30 firestore.rules
      drwxr-xr-x  10   staff   320 May 13 15:32 functions
      
      
    • Now you have installed a new Firebase Functions Project!

Installing Project Dependencies

  • Open the project in your Code Editor
  • The directory structure should look like this:

    # Project Structure Overview
    
    - `functions-express-ts-project-guide`
      - `functions`
        - `node_modules`
        - `src`
          - `index.ts`
          - `.eslintrc.js`
          - `.gitignore`
          - `package.json`
          - `package-lock.json`
          - `tsconfig.dev.json`
          - `tsconfig.json`
        - `.firebaserc`
        - `.gitignore`
        - `firebase.json`
        - `firestore.indexes.json`
        - `firestore.rules`
    
    ### functions
    This directory contains all the source code and configuration for Firebase Functions.
    
    #### node_modules
    - **Purpose:** Contains all the npm packages that are installed as dependencies for the project. Managed by npm.
    
    #### src
    This directory holds the TypeScript source files for the Firebase Functions.
    
    ##### index.ts
    - **Purpose:** The main entry point for Firebase Functions, contains the TypeScript code for defining cloud functions.
    
    ##### .eslintrc.js
    - **Purpose:** Configuration file for ESLint, a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, aiming to make code more consistent and avoiding bugs.
    
    ##### .gitignore
    - **Purpose:** Specifies intentionally untracked files that Git should ignore. Files already tracked by Git are not affected.
    
    ##### package.json
    - **Purpose:** Defines npm package dependencies for the project, as well as build scripts and project metadata.
    
    ##### package-lock.json
    - **Purpose:** Automatically generated file which specifies the exact versions of all npm dependencies that were installed for the project. Ensures a consistent environment for all installations of the dependencies.
    
    ##### tsconfig.dev.json
    - **Purpose:** The TypeScript compiler configuration file for development environments, may differ slightly in settings from production to enable better debugging or more verbose logging.
    
    ##### tsconfig.json
    - **Purpose:** The TypeScript compiler configuration file for the project. Defines options required to compile the project.
    
    #### .firebaserc
    - **Purpose:** Firebase CLI runtime configuration file. Stores aliases and project specific settings used by Firebase.
    
    #### .gitignore (in functions directory)
    - **Purpose:** Similar to the src .gitignore, but for the entire functions directory.
    
    #### firebase.json
    - **Purpose:** Firebase configuration file which defines rules and settings for your Firebase project, like hosting behavior and cloud functions paths.
    
    #### firestore.indexes.json
    - **Purpose:** Configuration file for defining indexes in Firestore. Helps improve query performance.
    
    #### firestore.rules
    - **Purpose:** Security rules file for Firestore. Defines what data can be accessed by whom, securing your Firestore data based on authentication and authorization.
    
    
  • Open the index.ts file

  • You should see an auto generated code, let’s remove all the code for now

  • This will be our entry file and we need to create a new Express application

1. Install Express

  • Let’s firs install express by running:

    # Important: First, move into the functions directory, this is where the package.json file lives.
    # We will run all our commands from this directory.
    cd functions
    # Install Express
    npm install express
    # You should see express on your package.json file dependencies
    
  • If you take a look at the package.json there’s auto generated content by the Firebase CLI, there are already some scripts, dependencies, and all we need to start developing

2. Do some code

  • Add the following to the index.ts file and read it carefull:

    // For our API we will use the Functions 2nd Gen HTTP Request trigger
    // See this: https://firebase.google.com/docs/functions/http-events?gen=2nd
    // Import onRequest from firebase-functions for HTTP triggers.
    import {onRequest} from "firebase-functions/v2/https";
    
    // Import the entire Express module. This allows us to use its
    // functionalities to create and manage the server.
    import * as express from "express";
    
    // Import the Request and Response types from the 'express' module.
    // These types are used to type the request and response objects in
    // route handlers, providing type checking and IntelliSense features in the IDE.
    import {Request, Response} from "express";
    
    // Create a new Express application by calling `express()`.
    // This `app` object encapsulates all the functionalities of an
    // Express application.
    // It's used to configure routes, middleware, and to start the server.
    const app = express();
    
    // Define a route handler for HTTP GET requests to the root URL ("/").
    // This sets up the server to respond to GET requests at the
    // specified path. Here, the path is the root URL.
    // eslint-disable max-len
    // `req` (request) and `res` (response) are parameters typed with
    // `Request` and `Response` to enhance type safety and tooling support.
    // The handler function sends the text "Hello World!" back to the
    // client when the root URL is accessed.
    app.get("/", (req: Request, res: Response) => res.send("Hello World!"));
    
    // Export the `app` instance as `api`. This exported `api` can be used
    // elsewhere, particularly in Firebase Functions, to handle
    // HTTP requests. This allows the `api` to act as a
    // serverless function in the Firebase ecosystem.
    exports.api = onRequest(app);
    
    
  • Now build the project to update the emulators server with npm run build this will create a lib directory which will be the one to actually deploy to the Cloud Functions.

3. Start the Emulators

  • Now, go back the package.json file.
  • See the command serve , run it with npm run serve
  • You’ll see something like this:

    βœ”  functions: Loaded functions definitions from source: api.
    # Important: this is the URL you will use to call the API
    βœ”  functions[us-central1-api]: http function initialized (http://127.0.0.1:5001/my-project/us-central1/api).
    
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ βœ”  All emulators ready! It is now safe to connect your app. β”‚
    β”‚ i  View Emulator UI at http://127.0.0.1:4000/               β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Emulator  β”‚ Host:Port      β”‚ View in Emulator UI             β”‚
    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
    β”‚ Functions β”‚ 127.0.0.1:5001 β”‚ http://127.0.0.1:4000/functions β”‚
    
    
  • Go to http://localhost:4000/ and you should see the Emulators interface, although only the Functions emulator is running for now in the URL: http://127.0.0.1:5001/my-project/us-central1/api

  • Open Postman

  • Create a new Request and do a GET to the URL

  • The Response should be "Hello World!"

That's it! you have now created a Hello World with Firebase Functions, Express and Typescript. In part 2 we will cover initializing Firestore and performing the CRUD operations for a Pets REST API.

Sentry image

See why 4M developers consider Sentry, β€œnot bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay