Sé que arrayUnion no acepta duplicados, pero ¿hay alguna forma de evitarlo y actualizar solo un campo (cantidad) si el elemento está duplicado? Tal vez tenga otra idea de cómo estructurar mis datos para lograr esto si no existe una solución para esto. Gracias
y aquí está la función donde trato de hacer eso (ofc esto no funciona porque asíncrono):
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'); } }No hay ninguna forma directa de hacerlo. Tendrá que leer el documento, verificar si el artículo ya existe en esa matriz, si lo hace, entonces incremente la cantidad y actualice toda la matriz nuevamente. Si no, puede agregarlo en la matriz.
No estoy seguro de si obtienes la información del carrito existente para mostrársela al usuario. Si lo hace en la carga inicial, puede verificarlo directamente desde el estado local (donde se almacena la información del carrito) y actualizarlo en consecuencia.
Bien, creo que encontré una solución alternativa: aquí está el código para la función y funciona como se esperaba:
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'); } }