How to solve FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore problem?
E

7

30

I am trying to set up Firebase with next.js. I am getting this error in the console.

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

This is one of my custom hook

import { onAuthStateChanged, User } from '@firebase/auth'
import { doc, onSnapshot, Unsubscribe } from 'firebase/firestore'
import { useEffect, useState } from 'react'
import { auth, fireStore } from './firebase'

export const useUserData = () => {
  const [username, setUsername] = useState<string | null>(null)

  const [currentUser, setCurrentUser] = useState<User | null>(null)

  useEffect(() => {
    let unsubscribe: void | Unsubscribe

    onAuthStateChanged(auth, (user) => {
      if (user) {
        setCurrentUser(user)
        // The Problem is inside this try blog
        try {
          // the onsnapshot function is causing the problem
          console.log('firestore: ', fireStore)
          unsubscribe = onSnapshot(doc(fireStore, 'users', user.uid), (doc) => {
            setUsername(doc.data()?.username)
          })
        } catch (e) {
          console.log(e.message)
        }
      } else {
        setCurrentUser(null)
        setUsername(null)
      }
    })

    return unsubscribe
  }, [currentUser])

  return { currentUser, username }
}

I also have this firebase.ts file where I initialized my firebase app

import { FirebaseApp, getApps, initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
import { getFirestore } from 'firebase/firestore/lite'
import { getStorage } from 'firebase/storage'

const firebaseConfig = {
  apiKey: 'some-api',
  authDomain: 'some-auth-domain',
  projectId: 'some-project-id',
  storageBucket: 'some-storage-bucket',
  messagingSenderId: 'some-id',
  appId: 'some-app-id',
  measurementId: 'some-measurement-id',
}

let firebaseApp: FirebaseApp

if (!getApps.length) {
  firebaseApp = initializeApp(firebaseConfig)
}

const fireStore = getFirestore(firebaseApp)
const auth = getAuth(firebaseApp)
const storage = getStorage(firebaseApp)

export { fireStore, auth, storage }

I don't know whether the problem is in the project initialization. I am pretty sure the error is generated from my custom hook file. I also found out that there must be something wrong with onSnapshot function. Am I passing the docRef wrong or something? What am I doing wrong here?

The console.log(firestore) log:


    type: "firestore-lite"
    _app: FirebaseAppImpl
    _automaticDataCollectionEnabled: false
    _config: {name: "[DEFAULT]", automaticDataCollectionEnabled: false}
    _container: ComponentContainer {name: "[DEFAULT]", providers: Map(15)}
    _isDeleted: false
    _name: "[DEFAULT]"
    _options:
    apiKey: 'some-api'
    authDomain: 'some-auth-domain'
    projectId: 'some-project-id'
    storageBucket: 'some-storage-bucket'
    messagingSenderId: 'some-id'
    appId: 'some-app-id'
    measurementId: 'some-measurement-id'
    [[Prototype]]: Object
    automaticDataCollectionEnabled: (...)
    config: (...)
    container: (...)
    isDeleted: (...)
    name: (...)
    options: (...)
    [[Prototype]]: Object
    _credentials: Q {auth: AuthInterop}
    _databaseId: H {projectId: "next-firebase-fireship", database: "(default)"}
    _persistenceKey: "(lite)"
    _settings: ee {host: "firestore.googleapis.com", ssl: true, credentials: undefined, ignoreUndefinedProperties: false, cacheSizeBytes: 41943040, …}
    _settingsFrozen: false
    app: (...)
    _initialized: (...)
    _terminated: (...)

Ewart answered 3/9, 2021 at 16:13 Comment(4)
Hmm... can you try doc(fireStore, collection('users'), user.uid), with collection also being imported from 'firebase/firestore'?Hypochondria
Oops, sorry, That actually gives a type errorEwart
Can you share a screenshot of logs? console.log('firestore: ', fireStore) What does this log? The error says Expected first argument to collection() even for doc() method atm.Appomattox
@Appomattox I edited the question. Take a lookEwart
A
65

Using getFirestore from lite library will not work with onSnapshot. You are importing getFirestore from lite version:

import { getFirestore } from 'firebase/firestore/lite'

Change the import to:

import { getFirestore } from 'firebase/firestore'

From the documentation,

The onSnapshot method and DocumentChange, SnapshotListenerOptions, SnapshotMetadata, SnapshotOptions and Unsubscribe objects are not included in lite version.


Another reason for this error to show up could be passing invalid first argument to collection() or doc() functions. They both take a Firestore instance as first argument.

// Ensure that "db" is defined and initialized
const db = getFirestore();
// console.log(db);

const colRef = collection(db, "collection_name");
Appomattox answered 3/9, 2021 at 16:35 Comment(4)
The lite version is useful only if you don't need real time listeners and basic CRUD operation are suffiecient.Appomattox
still not working in my codes. : (Glottology
: ) corrected error. I had combined codes of firebase "Web Version 9" and "Web Version 8"Glottology
works like charm :)Doorjamb
H
13

Don't mix usage of firestore/lite with firestore

You need to use in your imports either:

'firebase/firestore'

OR

'firebase/firestore/lite'

Not both in the same project.

In your case, the firebase.ts file is using:

import { getFirestore } from 'firebase/firestore/lite'

And in your hook:

import { doc, onSnapshot, Unsubscribe } from 'firebase/firestore'

So you're initialising the lite but using the full version afterwards.

Keep in mind that both has it's benefits, but I would suggest in your case to pick one and just use it. Then the error will be gone.

Harmsworth answered 3/6, 2022 at 13:35 Comment(1)
This was it for me. I thought I could use "lite" on some pages and not others.Thunderstruck
I
4

Adding to @Dharmaraj, if you are using firebase react hooks, use the reverse.

Instead of

import { getFirestore } from 'firebase/firestore'

Use

import { getFirestore } from 'firebase/firestore/lite'
Indigene answered 10/1, 2022 at 18:13 Comment(0)
G
3

If you are using firebase lite then collection is not used.

Firebase lite example:

import {
 getFirestore,
 getDoc,
 updateDoc,
 doc
} from '@firebase/firestore/lite';

const firestore = getFirestore(app);
const docRef = doc(firestore, 'collection/doc');
const docSnap = await getDoc(docRef);
await updateDoc(docRef, "field", 'value');

When to use Firestore Lite
It can be tricky to decide when to let go of the standard Firestore SDK's offline persistence and caching features. You should understand these features before deciding to trade them away for the lower overhead of Firestore Lite. In general, weigh these factors when deciding whether to use Firestore Lite:

  1. Online status - Firestore Lite is good for apps that do not need live updates and have connectivity.
  2. Size constraints - Firestore Lite is great if you want to reduce your overall JavaScript bundle size.

Read more here

Garrek answered 2/6, 2022 at 8:58 Comment(0)
P
3

This can happen if you have both @firebase/firestore and firebase installed and there is a version mismatch.

firebase comes with @firebase/firestore. Remove any @firebase/... dependencies so that you're using the same version that firebase uses.

Piedadpiedmont answered 17/6, 2022 at 19:59 Comment(0)
K
0

In my case the reason as mentioned by other answers, yet there is one important part, as i was following old tutorial with next js 13 and firebase v9.

In my firebase.tsx the configuration file for firebase it self, was pointing to /lite

Changed this

    import { getFirestore } from "firebase/firestore/lite";

To this

    import { getFirestore } from "firebase/firestore";
Kansu answered 2/12, 2023 at 16:35 Comment(0)
C
0

had the same issue. In my case, it occurred because I used Firebase in a different folder inside a monorepo, resulting in two instances of Firestore running.

Moving the initialization to one place resolved the issue

Comply answered 13/5 at 5:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.