I'm trying to create a variable to reference a Firestore document.
const userRef = doc(db, 'users', uid)
and use it by adding a Realtime listener
onSnapshot(userRef, (doc) => {
if (doc.exists()){
setCode(code = doc.data().keycode)
} else {
setCode(code = 'N/A')
}
})
But it gets this error
FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore
At first, I thought it was because the uid is incorrect, so I hard coded it, and still has the same error.
Here's the full code, it's a react component. I imported the firebase config from App.js
import React, { useState } from 'react'
import { onSnapshot, doc, getFirestore } from 'firebase/firestore'
function Transaction(uid, firebase) {
const db = getFirestore(firebase);
let [amount, setAmount] = useState('')
let [target, setTarget] = useState('')
let [code, setCode] = useState('')
const userRef = doc(db, 'users', uid)
const sendNum = async(e) => {
e.preventDefault();
console.log('Send Num')
}
const generateCode = async(e) => {
e.preventDefault();
console.log('Generate Code')
}
onSnapshot(userRef, (doc) => {
if (doc.exists()){
setCode(code = doc.data().keycode)
} else {
setCode(code = 'N/A')
}
})
return (
<>
<form onSubmit={sendNum}>
<input style={{ width: 200 }}value={amount} onChange={(e) => setAmount(e.target.value)} type="number" placeholder='Amount'/>
<input style={{ width: 200 }} value={target} onChange={(e) => setTarget(e.target.value)} type="number" placeholder='Keycode'/>
<br />
<button className='btn' type='submit'>Send</button>
</form>
<section>
<h2>{code}</h2>
<button className='btn' onClick={generateCode} type='submit'>Generate Code</button>
</section>
</>
)
}
export default Transaction
I used React Router and passed the props in there.
const firebaseConfig = {
apiKey: "AIzaSyAKLyeY2FbjFDD57Kp9sGDi8uHg3neXxjI",
authDomain: "digitots-dev.firebaseapp.com",
projectId: "digitots-dev",
storageBucket: "digitots-dev.appspot.com",
messagingSenderId: "150130182744",
appId: "1:150130182744:web:216e77264273772c94182d",
measurementId: "G-RJT8Q1LSXZ"
};
const firebaseApp = initializeApp(firebaseConfig);
const auth = getAuth();
const db = getFirestore();
const provider = new GoogleAuthProvider();
let uid = ''
function App() {
return (
<div className="App">
<header>
<Router>
<Nav />
<Switch>
<Route path='/' exact component={MainView} />
<Route path="/about" component={About}/>
<Route path='/shop' component={Shop}/>
<Route path='/admin' component={Admin}/>
<Route
path='/portal'
render={(props) => (
<Transaction {...props} db={db} uid={uid} firebase={firebaseConfig}/>
)}
/>
</Switch>
</Router>
</header>
</div>
);
}

Apparently the error says Expected first argument to collection() even if you pass invalid arguments in doc(). That being said, db is undefined or is not an instance of Firestore. Make sure you are importing db from the file where you initialize Firestore or it's defined in same file:
import { getFirestore, doc } from "firebase/firestore"
const db = getFirestore(app) // const app = initializeApp(fireConfig)
const userRef = doc(db, 'users', uid)
About the TypeError: Cannot read property 'getProvider' of undefined error:
<Transaction {...props} db={db} uid={uid} firebase={firebaseConfig}/>
You are passing the Firebase config (a JSON object) into getFirestore() as a parameter while it expects the Firebase app instance.
// Incorrect
const db = getFirestore(firebase);
// Correct
const db = getFirestore(firebaseApp)
Change the Transaction component to:
<Transaction {...props} uid={uid} firebase={firebaseApp}/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With