DEV Community

Bernardo Cassina
Bernardo Cassina

Posted on

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.

Top comments (0)