Reputation: 3705
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: (...)
Upvotes: 35
Views: 52080
Reputation: 11
I have this issue on my side with the right path of the collection and with the right import, and just a yarn install
fix it.
Upvotes: 0
Reputation: 133
Monorepo issue: Had to run npm i
in the root folder, instead of only inside of one of the /apps or /packages folder.
Upvotes: 0
Reputation: 1541
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
Upvotes: 1
Reputation: 9581
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";
Upvotes: 1
Reputation: 4795
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.
Upvotes: 3
Reputation: 309
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:
Upvotes: 3
Reputation: 2368
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.
Upvotes: 14
Reputation: 402
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'
Upvotes: 4
Reputation: 50930
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 andDocumentChange
,SnapshotListenerOptions
,SnapshotMetadata
,SnapshotOptions
andUnsubscribe
objects are not included inlite
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");
Upvotes: 68