Search code examples
node.jsfirebase-admin

Cannot export firebase-admin's initializeApp function


In an attempt to abstract the firebase-admin dependency, I have a file index.js that is meant to export the functionality my project uses. Why is it not possible to export the initializeApp as a property?

For example:

index.js

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

exports.initializeApp = firebaseAdmin.initializeApp;

consumer.js

const firebaseAdmin = require('path/to/index.js');

firebaseAdmin.initializeApp();

The following error is thrown:

TypeError: Cannot read property 'initializeApp' of undefined

In an attempt to isolate the issue, I wrote the following to prove that initializeApp cannot be exported as a property, as I've done with other functions:

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

const initializeApp = firebaseAdmin.initializeApp;

initializeApp();

This throws:

TypeError: Cannot read property 'INTERNAL' of undefined

Why can I not export initializeApp as a property? This error has forced me to rewrite the export in index.js to:

exports.initializeApp = () => firebaseAdmin.initializeApp();

But this feels like a hack.

Does it make a difference that every one of my files starts with 'use strict;'? That would be surprising.


Solution

  • This is a result of how the Admin SDK is implemented. The main export of the Admin SDK package is not a real module, but an instance of a class. So when you extract a single method from that class instance, it looses all its context, and internal references like this starts malfunctioning. Here's a simplistic example to illustrate the problem.

    // file: sdk.ts
    class Firebase {
      public INSTANCE = {key: 'sdk'};
    
      public initializeApp() {
        console.log('Initializing', this.INSTANCE['key']);
      }
    }
    
    const admin = new Firebase();
    export = admin;
    
    # File: test.js
    // admin actually points to an instance of the Firebase class
    const admin = require('./sdk');
    
    // extract a single method from the object instance
    const initializeApp = admin.initializeApp;
    
    // The "this" reference in the initializeApp method no longer works
    initializeApp();
    

    You will have to continue using the workaround you've found for now. It might get addressed in a future release of the SDK, but right now it's not supported.