Tengo esta colección de artículos de firestore:
Quería disminuir las existencias después de enviar el formulario: tengo estos where() para comparar si lo que el usuario eligió es el mismo artículo que el que se guardó en Firestore.
function incrementCounter(collref) { collref = firestore .collection("items") .doc() .where(selectedItem, "==", selectedItem); collref.update({ stocks: firestore.FieldValue.increment(-1), }); } Así es como enviaré mi formulario y configuraré incrementCounter() después de guardarlo:
const handleSubmit = (e) => { e.preventDefault(); try { const userRef = firestore.collection("users").doc(id); const ref = userRef.set( { .... }, }, { merge: true } ); console.log(" saved"); incrementCounter(); } catch (err) { console.log(err); } }; No hay ningún error al enviar el formulario. Sin embargo, incrementCounter() no funciona y muestra este error:
TypeError: _Firebase_utils__WEBPACK_IMPORTED_MODULE_5__.firestore.collection(...).doc(...).where is not a functionHay pocos problemas aquí
firebase.firestore.FieldValue not firestoreFieldValuewhere la cláusula se usa para la colección, no doc(), así que elimínelo también. Además, no creo que esto actualice la colección completa, pero verifíquelo y vea. (El error que está recibiendo es debido a esto)No sé cómo está importando firebase en esta aplicación y no sé cómo ha declarado firestore, pero la mayoría de las variables de firestore se declaran así
const firestore = firebase.firestore();
Aquí firestore es una función, no una propiedad, pero cuando lo usa en FieldValue , debería ser como
firebase.firestore.FieldValue.increment(-1),
Tenga en cuenta que firestore aquí es una propiedad, no una función
Su código completo debería ser así
async function incrementCounter(collref) { collref = firestore .collection("items") .where(selectedItem, "==", selectedItem); const newRef = await collref.get(); for(let i in newRef.docs){ const doc = newRef.docs[i]; await doc.update({ stocks: firebase.firestore.FieldValue.increment(-1), }); // You can also batch this } } const handleSubmit = async (e) => { e.preventDefault(); try { const userRef = firestore.collection("users").doc(id); const ref = await userRef.set( { .... }, }, { merge: true } ); console.log(" saved"); await incrementCounter(); } catch (err) { console.log(err); } };El método where() existe en una CollectionReference y no en una DocumentReference . También debe obtener referencias a esos documentos primero, así que primero obtenga todos los documentos coincidentes y luego actualícelos todos usando Promise.all() o Batch Writes :
function incrementCounter() { // not param required ^^ const collref = firestore .collection("items") // .doc() <-- remove this .where(selectedItem, "==", selectedItem); // ^^^ ^^^ // doc field field value // "item" {selectedItemName} collRef.get().then(async (qSnap) => { const updates = [] qSnap.docs.forEach((doc) => { updates.push(doc.ref.update({ stocks: firebase.firestore.FieldValue.increment(-1) })) }) await Promise.all(updates) }) }Si está actualizando menos de 500 documentos, considere usar escrituras por lotes para asegurarse de que todas las actualizaciones fallen o pasen:
collRef.get().then(async (qSnap) => { const batch = firestore.batch() qSnap.docs.forEach((doc) => { batch.update(doc.ref, { stocks: firebase.firestore.FieldValue.increment(-1) }) }) await batch.commit() })Puede leer más sobre las escrituras por lotes en la documentación