ArkhamsFinest
ArkhamsFinest

Reputation: 253

Do i need to include admin.initializeApp(); in all my firebase cloud functions file (Typescript)?

Question: If i'd like to use firebase services in separate function files, do i have to include admin.initializeApp(); at the top of each file?

What is the current best practice of doing this?

I have a source folder containing 3 files

  1. auth.ts - admin.initializeApp is at the top of this file
  2. http.ts - Do i add it here if i want to use firebase services?
  3. index.ts

My index.ts file is:

export { basicHTTP, advanceHTTP, api } from "./http";
export { createUserRecord } from "./auth";

My auth.ts file uses the admin.firestore():

import * as functions from "firebase-functions";

import * as admin from "firebase-admin";

admin.initializeApp();

const db = admin.firestore();

export const createUserRecord = functions.auth
  .user()
  .onCreate((user, context) => {
    const userRef = db.doc(`users/${user.uid}`);
    return userRef.set({
      name: user.displayName,
      createdAt: context.timestamp,
      nickname: "bubba"
    });
  });

My http.ts file contains the following, what do i do if i want to use a firebase service within this function?:

import * as functions from "firebase-functions";

import * as admin from "firebase-admin";

// Express
import * as express from "express";
import * as cors from "cors";

// Most basic http function

export const basicHTTP = functions.https.onRequest((request, response) => {
  response.send("Hello from firebase");
});

export const advanceHTTP = functions.https.onRequest((request, response) => {
  const name = request.query.name;

  if (!name) {
    response.status(400).send("You must supply a name");
  }

  response.send(`Hi there ${name}`);
});

// Custom middleware

const auth = (request, response, next) => {
  if (!request.header.authorization) {
    response.status(400).send("Unauthorized. Access denied");
  }
  next();
};

// Multi Route ExpressJS HTTP Function

const app = express();

app.use(cors({ origin: true }));

app.use(auth);

app.get("/cat", (request, response) => {
  response.send("Cat");
});

app.get("/dog", (request, response) => {
  response.send("dog");
});

export const api = functions.https.onRequest(app);

Upvotes: 23

Views: 7960

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317467

The first time you run this:

import * as admin from "firebase-admin";
admin.initializeApp();

the admin returned from subsequent imports in other files will already be initialized. This is because all imports from a module yield the exact same object.

If you want to use firebase-admin in multiple places, you could probably just import and initialize it once at your function entry point (index.ts), then assume in all the other places that it's already been initialized:

import * as admin from "firebase-admin";
admin.initializeApp();
export { basicHTTP, advanceHTTP, api } from "./http";
export { createUserRecord } from "./auth";

Now you can simply import firebase-admin in your other modules and use admin without having to initialize it.

Upvotes: 24

Related Questions