Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
like image 719
ArkhamsFinest Avatar asked Oct 10 '18 14:10

ArkhamsFinest


People also ask

Does Firebase work with TypeScript?

Using an existing TypeScript project With this configuration, a firebase deploy --only functions command builds your TypeScript code and deploys it as functions.

How do I set environment variables in Firebase hosting?

If you need an alternative set of environment variables for your Firebase projects (such as staging vs production), create a . env. <project or alias> file and write your project-specific environment variables there. The environment variables from .

What is the difference between onCall and onRequest?

onRequest creates a standard API endpoint, and you'll use whatever methods your client-side code normally uses to make. HTTP requests to interact with them. onCall creates a callable. Once you get used to them, onCall is less effort to write, but you don't have all the flexibility you might be used to.


1 Answers

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.

like image 126
Doug Stevenson Avatar answered Oct 05 '22 13:10

Doug Stevenson