Firebase modules cause 'registerComponent' error in Svelte

Viewed 491

In my svelte project there is a firebase.js file that manages the firebase services. The file looks like this:

import firebase from "firebase/app"; // rollup bundle issue with ESM import
import "firebase/firestore";
import "firebase/auth";

const firebaseConfig = {
  // firebase config
};

console.log(firebase);

firebase.initializeApp(firebaseConfig);

export const auth = firebase.auth();
export const googleProvider = new firebase.auth.GoogleAuthProvider();

export const db = firebase.firestore();

This works perfectly fine, however adding firebase modules seems to cause issues. e.g. adding import "firebase/analytics"; after the firebase auth an error appears in the browser console

index.esm.js:1301 Uncaught TypeError: Cannot read property 'registerComponent' of undefined
    at registerInstallations (index.esm.js:1301)
    at index.esm.js:1325
    at main.js:6

the index.esm.js file in question is the @firebase/installations file, it appears that the object being passed into registerInstallations(firebase) isn't a firebase app object but is instead an object containing 2 firebase app objects, one named default and one named firebase.

The only way I've found to fix this is by replacing the calls to registerInstallations(firebase) with registerInstallations(firebase.firebase) in multiple places throughout node_modules, which does not seem like a good solution.

Edit: I managed to fix this by rebuilding the entire project, including the rollup config and the package.json. Looking through the git changes there are no differences that should have effected this.

2 Answers

URL hosting is not the best way of doing this. It is possible to get firebase to work in a bundle.

It requires slightly modifying the rollup.config.js file. Adding the following code to the rollup config plugins array fixed the issue for me. Resolve is imported from @rollup/plugin-node-resolve

resolve({
  browser: true,
  dedupe: (importee) =>
    importee === "svelte" || importee.startsWith("svelte/"),
  mainFields: ["main", "module"],
}),

I have a working version available in my fullstack template here. Just clone the repo and only use the ./frontend folder. Make sure to add your firebase web app config in the ./frontend/src/services/firebase.js file.

Here is my HTML. I use RxFire / RxJs to access firestore.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="author" content="voscausa">
  <meta name="viewport" content="width=device-width, , initial-scale=1.0">
  <title>my-project</title>
  <link rel='stylesheet' href='global.css'>
  <link rel='stylesheet' href='/build/bundle.css'>
</head>
<body>
  <script src="https://www.gstatic.com/firebasejs/7.18.0/firebase-app.js" defer></script>
  <script src="https://www.gstatic.com/firebasejs/7.18.0/firebase-auth.js" defer></script>
  <script src="https://www.gstatic.com/firebasejs/7.18.0/firebase-firestore.js" defer></script>
  <script src='/build/bundle.js' defer></script>
</body>
</html>

And the firebase.js (No need for firebase imports now);

var firebaseConfig = {
   // firebase config
};
firebase.initializeApp(firebaseConfig);
 
export const auth = firebase.auth();
export const googleProvider = new firebase.auth.GoogleAuthProvider();
export const db = firebase.firestore();
Related