5

I want to Initialize Firebase App in multiple files to organize my methods properly, but I not sure which is the best way to do so.

Below is the file system structure:

/functions
 |-keys
 |-methods
 |  |-email.js
 |  |-logger.js
 |-node_modules
 |-index.js
 |-package.json
 |-package-lock.json

In my index.js, I initialize 2 projects where 1 is for production and another is for OTE.:

const functions = require('firebase-functions');
var firebaseAdmin = require('firebase-admin');

var productionServiceAccount = require('./keys/production-key.json');
var oteServiceAccount = require("./keys/ote-key.json");

var prodServer = firebaseAdmin.initializeApp({
    credential: firebaseAdmin.credential.cert(productionServiceAccount),
    databaseURL: 'https://production-panel.firebaseio.com'
}, "prod");
var oteServer = firebaseAdmin.initializeApp({
    credential: firebaseAdmin.credential.cert(oteServiceAccount),
    databaseURL: "https://ote-panel.firebaseio.com"
}, "ote");

console.log("prodServer: ", prodServer.name, "oteServer: ", oteServer.name)

var mailer = require('./methods/email.js') //import code from method folder
var logger = require('./methods/logger.js') //import code from method folder

Below is how i handle the request whether use prod or OTE project:

let admin = req.headers.env == 'prod' ? prodServer : oteServer

Now the problem is my ./methods/logger.js want to read/write log into DB as well, but I don't know how/what to do.

Below is the `logger.js` code:
var exports = {}

exports.log = function(item, ref, env) {
    let admin = env == 'prod' ? prodServer : oteServer //<--problem here

    return admin.database().ref(ref).push(item)
}

module.exports = exports

Should I initialize firebase project again or import it from index.js?

-If initialize firebase project again it will say the project "name" has been used.

-If import it from index.js, then I have to export it from index.js, which when I deploy it to Firebase Function, it will become an onCall Methods..?

-If I move the initialize to another file (./method/initFirebase.js) and import it to index.js when I deploy it to Firebase Function, will it automatically initialize the firebase app?

Please advise. Thank you.

3 Answers 3

1

You can create one additional file like you said initFirebase.js and put your initilization and export code there.

const prodServer = firebaseAdmin.initializeApp({
    credential: firebaseAdmin.credential.cert(productionServiceAccount),
    databaseURL: 'https://production-panel.firebaseio.com',
}, 'prod');
const oteServer = firebaseAdmin.initializeApp({
    credential: firebaseAdmin.credential.cert(oteServiceAccount),
    databaseURL: 'https://ote-panel.firebaseio.com',
}, 'ote');
module.exports = {
    firebaseApp: env === 'prod' ? prodServer : oteServer,
};

And from all other file import firebase app

const firebaseApp = require('../YOUR_initFirebase.js')

So you dont need to worry about environment in each of the files and it is working for me on google cloud functions.

Sign up to request clarification or add additional context in comments.

1 Comment

will the initFirebase.js successfully export when the env is not declare in the file? My env mostly come in together with the HTTP request.
0

Here is how you can manage multiple apps with firebase-admin on nodejs to ensure the apps are not reinitialised.

const admin = require('firebase-admin');
const service1 = require('./app1-service.json');
const service2 = require('./app2-service.json');

const apps = {
  app1: null,
  app2: null,
};

void init() {
  // check and init app1
  const initialisedApps = admin.apps.map((item) => item.name);
  if (!initialisedApps.includes('app1')) {
    apps.app1 = admin.initializeApp({
      credential: admin.credential.cert(service1),
    }, 'app1');
  } else apps.app1 = admin.app('app1');
  
  // check and init app2
  if (!initialisedApps.includes('app2')) {
    apps.app2 = admin.initializeApp({
      credential: admin.credential.cert(service2),
    }, 'app2');
  } else apps.app2 = admin.app('app2');
}

Comments

0

The way I solved this for ts is:

index.ts

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);

exports.auth = require('./methods/email.ts');

...

email.ts

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

// Get emails
exports.getEMail = functions.https.onCall(async (data, context) => {

  const uid = context?.auth?.uid ? context.auth.uid : '';
  const email = await admin.firestore().collection('emails').doc(uid).get();

  return email;
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.