Home  >  Q&A  >  body text

Unable to read Firestore DB from custom npm package using Firestore object passed from application

I'm trying to write my own npm package that uses the Firestore database. I initialize the class from the package using the Firestore object passed from the application:

import { firestoreTest } from 'my-package'

const app = initializeApp(firebaseConfig)
const db = getFirestore(app)
const test = new firestoreTest(db)

When I call the function from the package await test.getDoc('pathto/doc') I get the error: Uncaught (in promise) FirebaseError: Expected first argument to collection() to be a CollectionReference, DocumentReference, or FirebaseFirestore

I tried different combinations of initializing Firestore objects for reading from Firestore. Only if I fully initialize the Firebase app in the package using firebaseConfig I can read data from Firestore, but then I don't inherit the authentication from the parent app and can only read the publicly accessible collection.

I even tried passing doc(db, documentPath) to the package and I got an error telling me what might be happening: The type does not match the expected instance. Are you passing a reference from a different Firestore SDK?

So I thought using Firebase from my package would create a separate Firebase SDK instance.

I am using the same firebase package version in my app and package and also set the package firebase as a peer dependency.

I want to seamlessly use the same Firebase object that is initialized in my package's main app.

Can someone help me understand if there is something I can do to achieve this?

This is the code from my test package.

export class firestoreTest {
  private db: Firestore
  private app: FirebaseApp
  private dbFromApp: Firestore
  private localApp: FirebaseApp
  private localDb: Firestore

  constructor(firebaseConfig: FirebaseOptions, app: FirebaseApp, db: Firestore) {
    this.db = db
    this.app = app

    this.dbFromApp = getFirestore(app)

    this.localApp = initializeApp(firebaseConfig)
    this.localDb = getFirestore(this.localApp)
  }

  public async getDoc(docPath: string, ref?: DocumentReference<DocumentData, DocumentData>) {
    /* Reads data, but without authenticated user context */
    /* Uncaught (in promise) FirebaseError: Missing or insufficient permissions. */
    // const data = await getDoc(doc(this.localDb, docPath).withConverter(converter<any>()))

    /* Uncaught (in promise) FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore */
    // const data = await getDoc(doc(this.dbFromApp, docPath).withConverter(converter<any>()))

    /* Uncaught (in promise) FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore */
    const data = await getDoc(doc(this.db, docPath).withConverter(converter<any>()))

    /* Uncaught (in promise) FirebaseError: Type does not match the expected instance. Did you pass a reference from a different Firestore SDK? */
    // const data = ref && (await getDoc(ref.withConverter(converter<any>())))

    console.log(data?.data())
  }
}

renew

I tried installing the package from local sources and using symlinks to my local repository, but that didn't help.

Then I pushed my package repository to GitHub and installed the package using the GitHub repository as source and now it works.

It seems that when using local sources, my package always uses a separate Firebase instance. Putting the whole package project folder into my application folder and using partial package like app didn't help either.

Installing from GitHub is not a development solution, so I ended up creating folders in my app project and placing all the package files in them as if they were part of my app. After editing them I will copy to the package repository.

I don’t know if there is a better solution.

renew

I found package relative-deps that solved my development problem.

P粉064448449P粉064448449405 days ago502

reply all(1)I'll reply

  • P粉080643975

    P粉0806439752023-09-11 09:27:04

    Since the original poster answered his/her question by editing the question. This content is posted to increase awareness of the community:


    In npm, relative-deps refers to a feature that allows you to define dependencies using relative file paths within a local package or workspace.

    This feature was added in npm version 7. You can directly reference other packages or modules in your project, rather than relying on package names and the npm registry.

    This makes development easier, especially for projects using monorepos or a large number of interrelated packages. npm Resolve and install dependencies based on the file paths specified in the package.json file.


    Note: Only npm versions starting with v7 and above support this feature.

    reply
    0
  • Cancelreply