I have these collection of items from firestore:
I kind of wanted to decrement the stocks after submitting the form: I have these where() to compare if what the user chose is the same item from the one saved in the firestore.
function incrementCounter(collref) {
collref = firestore
.collection("items")
.doc()
.where(selectedItem, "==", selectedItem);
collref.update({
stocks: firestore.FieldValue.increment(-1),
});
}
This is how I'll submit my form and I've set the incrementCounter() after saving it:
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);
}
};
There's no error in submitting the form. However, the incrementCounter() is not working and displays this error:
TypeError: _Firebase_utils__WEBPACK_IMPORTED_MODULE_5__.firestore.collection(...).doc(...).where is not a function
There are few problems here
firebase.firestore.FieldValue not firestoreFieldValuewhere clause is used for collection, not doc() so remove that as well. Also I don't think this will update the full collection but do check it and see. (The error you are getting is because of this)I don't know how you are importing firebase in this application and I don't know how you have declared firestore but mostly firestore variable is declared like this
const firestore = firebase.firestore();
In here firestore is a function, not a property
But when you are using it in the FieldValue then it should be like
firebase.firestore.FieldValue.increment(-1),
Notice that firestore here is a property not a function
Your full code should be like this
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);
}
};
The where() method exists on a CollectionReference and not a DocumentReference. You also need to get references to those documents first so first get all the matching documents and then update all of them using Promise.all() or 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)
})
}
If you are updating less than 500 documents, consider using batch writes to make sure all updates either fail or pass:
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()
})
You can read more about batch writes in the documentation