How to pass a Firestore collection reference to a library

I have a utility function that works fine as long as I keep it in my codebase. It takes a CollectionReference and a document id as arguments.

When I move it to a shared library I get the following error:

FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore

The collection reference fails the instanceof check that is done internally by firebase/firestore.

The code exported from my library is clean ESM and I have made sure that all places import from firebase/firestore and use the same versions. So I don’t know what else I can try.

Here is the code as it is exported by the library:

import { CollectionReference, doc, getDoc } from "firebase/firestore";
import { useEffect, useState } from "react";
function useDocumentDataOnce(collectionRef, documentId) {
  const [data, setData] = useState();
  useEffect(() => {
    const fetchData = async () => {
      if (!documentId) {
        return;
      }
      console.log(
        "+++ collectionRef instanceof CollectionReference?",
        collectionRef instanceof CollectionReference
      );
      const ref = doc(collectionRef, documentId);
      const snapshot = await getDoc(ref);
      if (snapshot.exists()) {
        setData(snapshot.data());
      } else {
        throw new Error(`No document at ${collectionRef.path}/${documentId}`);
      }
    };
    fetchData().catch(console.error);
  }, [collectionRef, documentId]);
  return data;
}

If I use the exact same code, but imported from my codebase it works fine:

import { CollectionReference, doc, getDoc } from "firebase/firestore";
import { useEffect, useState } from "react";

export function useDocumentDataOnce<T>(
  collectionRef: CollectionReference,
  documentId?: string
) {
  const [data, setData] = useState<T>();

  useEffect(() => {
    const fetchData = async () => {
      if (!documentId) {
        return;
      }

      console.log(
        "+++ collectionRef instanceof CollectionReference?",
        collectionRef instanceof CollectionReference
      );

      const ref = doc(collectionRef, documentId);

      const snapshot = await getDoc(ref);
      if (snapshot.exists()) {
        setData(snapshot.data() as T);
      } else {
        throw new Error(`No document at ${collectionRef.path}/${documentId}`);
      }
    };

    fetchData().catch(console.error);
  }, [collectionRef, documentId]); // Add ref to the dependency array

  return data;
}

Here’s how the code is used on a Next.js page:

"use client";

import { db, useUserId } from "@/lib/firebase";
import { useDocumentDataOnce } from "failurebase";
import { collection } from "firebase/firestore";

type User = {
  displayName: string;
};

export default function UserProfilePage() {
  const userId = useUserId();
  const usersCollectionRef = collection(db, "users");

  const user = useDocumentDataOnce<User>(usersCollectionRef, userId);

  return <div>Hello {user?.displayName ?? "unknown"}</div>;
}

You can find the library code here. As you can see I have also made firebase a peer dependency, so nothing is bundled with my library code.

The library is also published on NPM. You can install it with failurebase@next

This is driving me nuts. Any idea what might be causing this?