I have 2 collections. a) Products: Stored Products, b) Barcode: Stores a prefix and a counter value which collectively forms a string and is used as ID for a new product.
app.post('/saveProduct',
body('name').not().isEmpty().trim().escape(),
body('description').not().isEmpty().trim().escape(),
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
// If error detected throw error
errors.array()['location'] = "";
return res.status(400).json({ errors: errors.array() });
}else{
let productData = {};
const BarcodeCollection = db.collection('Barcodes').doc('Code');
try {
let t_res = await db.runTransaction(async t => {
// Get the barcode which is to be used for the currect Product save request
const Barcodes = await t.get(BarcodeCollection);
// Assign Request object to ProductData Object
productData = {
"name": req.body.name,
"description": req.body.description,
"barcode": Barcodes.data().prefix+Barcodes.data().nextCode
};
// Increment Barcode nextCode
await t.update(BarcodeCollection, { nextCode: FieldValue.increment() });
// Use Product Barcode as ID and Store Product Data Oject
await db.collection('Products').doc(productData.barcode).set(productData);
});
console.log('Transaction Successful:');
return res.send({"status": 200, "message": "Product Saved", "barcode": productData.barcode});
}catch(e){
console.log('Transaction failure: '+ e);
return res.send({"status": 400, "message": "Something went wrong. Please try again later"});
}
}
});
The above code is what I am using.
Issue: The code I am using works fine but sometimes when there are multiple requests made within milliseconds. It overwrites the previously entered saved Product with a new Product. For example. I just stored Product with ID ABCD1003, within milliseconds I get another request and somehow it overwrites ABCD1003 instead of creating a new barcode as ABCD1004. If I detect whether the nextCode already exists in the system; if true then add 1 and save. There is always a chance that by the time I add 1, ABCD1004 might be used by another product and end up overwriting since requests are made within milliseconds.
How can I prevent overwriting? Note: I require the barcode to be unique if not sequential