I have a custom ID in my Firebase documents. I want to get a single document querying by that custom ID and modify it. I'm using firebase v9.
Here's my code so far:
const toggleLike = async () => {
const q = query(collection(db, 'mixrCocktails'), where('id', '==', cocktailId))
const querySnapshot = await getDocs(q)
const result: any[] = []
querySnapshot.forEach(doc => result.push(doc.data()) )
if (!isLiked) {
await updateDoc(result[0], { userLikes: arrayUnion(publisherId) })
setIsLiked(true)
}
else {
await updateDoc(result[0], { userLikes: arrayRemove(publisherId) })
setIsLiked(false)
}
}
The query works fine, but the problem is when I run updateDoc
. I get the following error:
Uncaught (in promise) FirebaseError: Expected type 'Zu', but it was: a custom Object object
I tried running result[0].update({ userLikes: arrayUnion(publisherId) })
and I get Uncaught (in promise) TypeError: result[0].update is not a function
.
I've also tried
const docRef = doc(db, "mixrCocktails", cocktail.id)
await updateDoc(docRef, { userLikes: arrayUnion(publisherId) })
And I get
Uncaught (in promise) TypeError: n.indexOf is not a function
In the docs (https://firebase.google.com/docs/firestore/manage-data/add-data) I see they use a document ref in the following way:
import { doc, updateDoc, arrayUnion, arrayRemove } from "firebase/firestore";
const washingtonRef = doc(db, "cities", "DC");
// Atomically add a new region to the "regions" array field.
await updateDoc(washingtonRef, {
regions: arrayUnion("greater_virginia")
});
In the example, I understand "DC" is the ID Firebase sets for the document. But how can I create a ref by querying for another field different than that?
Full code can be found here: https://github.com/coccagerman/mixr
Thanks in advance!
CodePudding user response:
Based on your question, if I understand it correctly. You want to query a document using where
before updating the document result.
You're not referencing the updateDoc()
properly. Check the snippet that I wrote based on your snippet above. Here's some options:
Using .map
:
const q = query(collection(db, 'mixrCocktails'), where('id', '==', cocktailId));
const querySnapshot = await getDocs(q);
const documents = querySnapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() }));
for (const document of documents) {
// console.log(document.id);
const documentRef = doc(db, 'mixCocktails', document.id);
if (!isLiked) {
await updateDoc(documentRef, { userLikes: arrayUnion(publisherId) })
setIsLiked(true)
}
else {
await updateDoc(documentRef, { userLikes: arrayRemove(publisherId) })
setIsLiked(false)
}
}
Using async
method:
async function updateDocuments (document) {
// console.log(document.id);
const documentRef = doc(db, 'mixrCocktails', document.id);
if (!isLiked) {
await updateDoc(documentRef, { userLikes: arrayUnion(publisherId) })
setIsLiked(true)
}
else {
await updateDoc(documentRef, { userLikes: arrayRemove(publisherId) })
setIsLiked(false)
}
}
const q = query(collection(db, 'mixrCocktails'), where('id', '==', cocktailId));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((document) => {
updateDocuments(document);
});
You may still improve the written code above for your use-case.