I'm coming from MongoDB and I'm struggling to understand getDoc()
and getDocs()
.
Do I understand this correctly?
Does getDoc()
only accept the document's ID as a parameter? Or can I do a query?
In the documentation I can only find code like this:
const docRef = doc(db, "collection", "11aa22bb33ccc");
const myDoc = await getDoc(docRef);
But what if I don't know the ID or I want to search with a different parameter, such as a field called author
? Is it correct that I would not be able to do that with getDoc()
?
With MongoDB, I can do db.collection.findOne({ author: "jones" })
.
Can I not do that with Firestore?
So if I want to use a query, do I always need to use getDocs()
?
If that is the case, I know that I can use limit(1)
but handling the response to retrieve that one document feels not-as-smooth-as-mongodb.
I tried this:
const documents = collection(firebaseDb, 'documents');
const query = query(documents, where('author', '==', 'jones'));
const authorDocs = await getDocs(query, limit(1));
console.log(authorDocs[0].data());
And I got an error: Cannot read properties of undefined (reading 'data')
So I think I have to use a forEach
, like this:
authorDocs.forEach(doc => console.log( doc.data() ));
But, for only one document? That seems odd. Is there a better way?
Does getDoc() only accept the document's ID as a parameter?
No, getDoc()
requires an argument of type document reference that points to a document that exists in a Firestore collection.
But what if I don't know the ID or I want to search with a different parameter, such as a field called author?
Then indeed you need to use a query that looks like this:
const queryByAuthor = query(collection(db, "documents"), where("author", "==", "jones"));
Is it correct that I would not be able to do that with getDoc()?
Yes, getDoc()
is used to read a single document and not multiple documents that a query returns. If you want to read all documents then indeed you need to use getDocs() and loop over the results:
const querySnapshot = await getDocs(queryByAuthor);
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
If you only want to read the first document, then you should read the document at index 0, querySnapshot[0]
:
const querySnapshot = await getDocs(queryByAuthor);
if (querySnapshot.docs.length > 0) {
const doc = querySnapshot.docs[0];
console.log('Document data:', doc.data());
}
Besides that, always be sure to not use undefined objects to create references or Firestore queries.