'Using module bundlers and dynamic config firebase
I have an issue where I cannot use init.js, which I have done in the past when importing firebase through the reserved hosting urls.
<script src="/__/firebase/init.js"></script>
This is the script that I am trying to use, and I am importing my firebase modules with:
import * as firebase from "firebase/app";
But I am trying to use webpack, with this. I have tried including init.js in my html, and my bundle as well, but without success.
Is there any way to use init.js with my module bundler?
Solution 1:[1]
Pretty late to the party, but better late than never if somebody needs it :)
We wanted to do the same at my company, for two reasons
- not having to specify the firebase config ourself, as the
init.jsscript contains it - automatic pickup of emulators when the
useEmulator=truequery param is specified (handy when you want to choose which emulators to start)
So we trick the script into doing what we want!
Basically the script looks for a global firebase variable which does not exist when using the modules. So we provide one for it to work.
Here's the code we use:
import { initializeApp } from 'firebase/app';
import { connectAuthEmulator, getAuth } from 'firebase/auth';
import { getFirestore, connectFirestoreEmulator } from 'firebase/firestore';
import { connectFunctionsEmulator, getFunctions } from 'firebase/functions';
export async function initFirebase(): Promise<void> {
// provide a fake firebase proxy object to the hosting init script
// to get the boilerplate done (firebase conf + automatic connection
// to started emulators)
const proxy: any = {
initializeApp: (c: any) => initializeApp(c),
};
// emulators done under development check to help with the tree-shaking
if (process.env.NODE_ENV === 'development') {
proxy.firestore = () => ({
useEmulator: (h: any, p: any) =>
connectFirestoreEmulator(getFirestore(), h, p),
});
proxy.functions = () => ({
useEmulator: (h: any, p: any) =>
connectFunctionsEmulator(getFunctions(), h, p),
});
proxy.auth = () => ({
useEmulator: (h: any, p: any) => connectAuthEmulator(getAuth(), h, p),
});
}
const _global = globalThis as any;
_global.firebase = proxy;
try {
await import(`/__/firebase/init.js${
process.env.NODE_ENV === 'development' ? '?useEmulator=true' : ''
}`
);
} finally {
delete _global.firebase;
}
}
You'll notice I only setup the proxies for firestore/functions/auth as those are the only ones we emulate at the moment. If you don't care for the emulators, you can skip the entire code paths when process.env.NODE is 'development'.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dharman |
