Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Firebase Admin across Express Routes

I'm using Cloud Functions and Firestore.

In my index.js, I initialize Firebase like so:

index.js

const admin = require("firebase-admin");
const functions = require("firebase-functions");
const usersApi = require("./api/users")
const paymentsApi = require("./api/payments")
const express = require('express');
const cors = require('cors');

admin.initializeApp(functions.config().firebase);

const db = admin.firestore()
const app = express();


const checkHeader = async(req, res, next) => {
  if(req.headers.authorization) {
    admin.auth().verifyIdToken(req.headers.authorization)
    .then(token => {
      req.uid = token.uid;
      req.email = token.email;
      req.stripeID = token.stripeID || null;
      return next();
    })
    .catch(e => {
      return next(e.errorInfo.code)
    })
  } else {
      return next('No token found');
  }
}

app.use(cors({origin: true}));
app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.use(checkHeader);

app.disable("x-powered-by");

app.use("/users", usersApi)
app.use("/payments", paymentsApi)

exports.api = functions.https.onRequest(app)

Then in my users router, i have the following:

api/users/index.js

const express = require('express');
const admin = require("firebase-admin");

const userRouter = express.Router();
const functions = require("firebase-functions");

const db = admin.firestore();

userRouter.post('/addUser', (req, res) => {
    return adminT.collection('users').doc(req.uid).set({
      activeSub: false,
      name: req.body.name
    })
    .catch(err => {
      throw new functions.https.HttpsError('unknown', err.message, {success:false, error: {err}})
    })
})

userRouter.post("*", (req, res) => {
  res.status(404).send("This route does not exist");
})

module.exports = userRouter;

I seem to get a couple of errors depending on how I configure my code. The first one in the setup as above is:

Error: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.

If I then initialize it within my Users route, I get told that the default Firebase instance has already been initialized.

How do I go about initalizing Firebase once, and then using it throughout my Cloud Function App?

like image 627
K20GH Avatar asked Jul 21 '18 08:07

K20GH


1 Answers

So I managed to get this working in the end.

In my index.js, I removed:

admin.initializeApp(functions.config().firebase);
const db = admin.firestore()

I created a file called fb.js:

const admin = require("firebase-admin");
const functions = require("firebase-functions");

module.exports = admin.initializeApp(functions.config().firebase);

Then edited my routes like so:

const express = require('express');
const userRouter = express.Router();
const fb = require('../../fb');
const db = fb.firestore()

userRouter.post('/addUser', (req, res) => {
    return db.collection('users').doc(req.uid).set({
      activeSub: false,
      name: req.body.name
    })
    .catch(err => {
      throw new functions.https.HttpsError('unknown', err.message, {success:false, error: {err}})
    })
})

userRouter.post("*", (req, res) => {
  res.status(404).send("This route does not exist");
})

module.exports = userRouter;
like image 143
K20GH Avatar answered Sep 23 '22 00:09

K20GH