如果项目是重复的 firestore,则更新数组中的地图元素

Update map element in array if item is duplicate firestore

我知道 arrayUnion 不接受重复项,但无论如何我可以阻止它并在项目重复时只更新一个字段(数量)吗?如果不存在解决方案,您可能对如何构建我的数据以实现此目标有另一种想法。谢谢

这是我的数据库:

这是我尝试执行此操作的函数(当然这不起作用,因为异步):

 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');
      }
    }

没有任何直接的方法可以做到这一点。您必须阅读文档,检查该项目是否已存在于该数组中,如果确实存在,则增加数量并更新整个数组。如果没有,那么您可以将其添加到数组中。

我不确定您是否获取现有购物车信息以向用户显示。如果您在初始加载时这样做,那么您可以直接从本地状态(存储购物车信息的地方)检查它并相应地更新。

好的,我想我找到了解决方法:这是该函数的代码,它按预期工作:

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');
      }
    }