Home > Net >  How to query a single document by custom parameter and update it in Firebase 9
How to query a single document by custom parameter and update it in Firebase 9

Time:03-03

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.

  • Related