Home > OS >  Update map element in array if item is duplicate firestore
Update map element in array if item is duplicate firestore

Time:04-19

I know that arrayUnion doesnt accept duplicates, but is there anyway I could prevent that and update just one field (quantity) if the item is duplicate? Maybe you have another idea of how to structure my data in order to achieve this if a solution for this doesnt exist. Thank you

Here is my db: firestore

and here is the function where I try to do that (ofc this doesnt work because async):

 const addProductToCart=async()=>{

   const q = query(collection(db, "carts"), where("userUID", "==", user?.uid));
      const docRef = await getDocs(q);
      if(docRef.docs[0].exists){
         console.log('not empty');

         let products=docRef.docs[0].data().products;
         products.forEach((product)=>{
           //product exists
           if(product.productUniqueName == uniqueProductName){
            //console.log(product)
            let cloneProduct=product;
            let updateProduct=product;
            updateProduct.quantity=product.quantity 1;
            console.log('Updated product' updateProduct);
            
            const currentUserCart=doc(db, 'carts', docRef.docs[0].id);
             updateDoc(currentUserCart, {
            cartItems: cartItems   1,
            products: arrayRemove(cloneProduct),
            products: arrayUnion(updateProduct)
         });
           return;
           }
          })


        //productUniqueName
         let newProduct={};
         newProduct.productName=product.name;
         newProduct.productBrand=product.brand;
         newProduct.price=product.price;
         newProduct.size=product.quantity;
         newProduct.quantity=1;
         newProduct.productUniqueName=uniqueProductName;
         newProduct.img=productImages[0];

         const currentUserCart=doc(db, 'carts', docRef.docs[0].id);
         await updateDoc(currentUserCart, {
         cartItems: cartItems   1,
         products: arrayUnion(newProduct)
       });

      }
      else{
        console.log('empty');
      }
    }

CodePudding user response:

There isn't any direct way to do so. You'll have to read the document, check if the item already exists in that array, if it does then increment quantity and update the whole array back. If not then you can add it in the array.

I'm not sure if you fetch existing cart information to show that to user. If you do so on initial load then you can check it directly from local state (where Cart info is stored) and update accordingly.

CodePudding user response:

Ok so, I think I found an workaround: here is the code for the function and it works as expected:

const addProductToCart=async()=>{

   const q = query(collection(db, "carts"), where("userUID", "==", user?.uid));
      const docRef = await getDocs(q);
      if(docRef.docs[0].exists){
         console.log('not empty');


         //added boolean to check if product exists/or not
         let productFound=false;
         let products=docRef.docs[0].data().products;

         let currentCartItems=docRef.docs[0].data().cartItems;
         products.forEach((product)=>{
           //product exists          
           
           if(product.productUniqueName == uniqueProductName){
            productFound=true;
            let updateProduct={...product};
            updateProduct.quantity=product.quantity 1;
            console.log('Updated product' updateProduct);
            
            const currentUserCart=doc(db, 'carts', docRef.docs[0].id);
            
//did Union and Remove separately
         updateDoc(currentUserCart, {
          cartItems: currentCartItems   1,
          products: arrayRemove(product)
       });

       updateDoc(currentUserCart, {
          products: arrayUnion(updateProduct)
     });
           //return;
           }
          })


        //productUniqueName
        if(productFound==false){
          console.log('product Not found')
          let newProduct={};
          newProduct.productName=product.name;
          newProduct.productBrand=product.brand;
          newProduct.price=product.price;
          newProduct.size=product.quantity;
          newProduct.quantity=1;
          newProduct.productUniqueName=uniqueProductName;
          newProduct.img=productImages[0];
           console.log('New Product', newProduct);
          const currentUserCart=doc(db, 'carts', docRef.docs[0].id);
          await updateDoc(currentUserCart, {
          cartItems: cartItems   1,
          products: arrayUnion(newProduct)
        });
        }
         
       setCartItems(cartItems 1);
      }
      else{
        console.log('empty');
      }
    }
  • Related