Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Firestore (v9) instance across packages

I'm trying to write some Firestore operations into a separate package so that it could be imported and reused in different web apps. I'm building a monorepo with different packages and I'm trying to use Firebase v9 for the following example:

From packageA I'm defining and exporting a getPosts(db) function that takes in a Firestore object and returns some posts form the given database

// in 'packageA'
import { collection, getDocs, Firestore } from 'firebase/firestore';

export const getPosts = async (db: Firestore) => {
  console.log('Passed in db: ', db); // This correctly prints the passed in Firestore object

  try {
    const postsCollection = collection(db, 'posts'); // This function will throw
    const querySnapshot = await getDocs(postsCollection);

    return querySnapshot.docs.map((doc) => doc.data());
  } catch (e) {
    console.error('Error reading posts: ', e);
  }
}

In a web app I'm initialising the Firebase app and exporting the Firestore instance

// firebase.js in 'web-app-1'
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';

const firebaseConfig = { /* my Firebase config */ };

export const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);

Then I'm trying to use the getPosts function from the package in a component...

// App.js in 'web-app-1'
import { db } from './firebase.js';
import { getPosts } from 'packageA';

let posts;

async function loadPosts() {
  try {
    posts = await getPosts(db);
  } catch (e) {
    console.error(e);
  }
}

loadPosts(); // throws an error

but I get the following error from the collection(db, 'posts') call

Error reading posts: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore

even though the passed in database is correctly printed in the console (form the getPosts function)

Note: If I copy the whole getPosts function and use it directly in the web app (i.e. without importing it from another package) then it works and correctly fetches the posts.

like image 763
arpi17 Avatar asked Jan 29 '26 08:01

arpi17


1 Answers

I've been looking around a bit more and found this answer to a similar question to solve my problem too.

Basically what I had to do is to specify Firebase as a peerDependency in packageA and not include it in the final bundle. The web apps that consume packageA will include Firebase as a regular dependency.

So the package.json files look as follows

In the utility package

{
  "name": "packageA",
  "peerDependencies": {
    "firebase": "^9.6.3"
  }
}

and then in the web apps

{
  "name": "web-app-1",
  "dependencies": {
    "firebase": "^9.6.3",
  }
}

This approach also makes sense to my use case as the web app – and only the web app – that initialises the Firebase app will include it in its bundle. I can imagine however that in some other use cases this is not a possible solution.

Nevertheless I have submitted my issue to the Firebase support as suggested and here is their answer:

We have received some similar cases and we are already working to solve this. However, it can take a while due the workload of the engineering team, please, be patient.

like image 186
arpi17 Avatar answered Jan 31 '26 22:01

arpi17