【问题标题】:How can I avoid duplicate data in Firebase / Cloud Firestore如何避免 Firebase / Cloud Firestore 中的重复数据
【发布时间】:2020-03-22 05:42:13
【问题描述】:
我正在制作一个网页,但输入相同的 ID 时应该会出现错误,但我无法做到。
function save () {
if (validate = true) {
console.log("exists!")
}else {
var imei = document.getElementById('imei').value;
var marca = document.getElementById('marca').value;
var referencia = document.getElementById('referencia').value;
var precio = document.getElementById('precio').value;
db.collection("phone").add({
Imei: imei,
Marca: marca,
Referencia: referencia,
Precio: precio
})
.then(function (docRef) {
document.getElementById('imei').value = '';
document.getElementById('marca').value = '';
document.getElementById('referencia').value = '';
document.getElementById('precio').value = '';
})
.catch(function (error) {
window.alert("Error adding document: ", error);
});
}
}save();
function validate () {
firebase.database().ref(`phone/${Imei}/imei`).once("value", snapshot =>
{ const imei = snapshot.val();
if (imei){
console.log("user exists!");
}
});
}
如果您能告诉我哪里出错或最佳解决方案,我将不胜感激
【问题讨论】:
标签:
javascript
firebase
firebase-realtime-database
【解决方案1】:
您的代码存在一些问题:
- 您正在使用
phone/${Imei}/imei 构建路径,但您的变量名拼写为imei(而不是Imei)。与大多数编程语言一样,JavaScript 中的大小写很重要,因此我建议密切注意拼写和大小写。
- 您没有在任何地方拨打
validate(),这意味着您的支票不会运行。
- 您没有从
validate() 返回任何内容。而且由于您要返回的内容来自异步调用中的数据库,因此您只能通过 promise 或async / await 来返回它。这个 aslome 可以保证自己的答案,所以我建议你研究 Firebase, retrieving data asynchronously、How to return values from async functions using async-await from function? 和 How to return value from an asynchronous callback function?
- 您确实应该使用事务来确保没有人可以在您的代码中的读写操作之间声明 IMEI。
- 如果 IMEI 值应该是唯一的,最好将其用作 key 而不是属性值。在此处阅读更多信息:
结合所有这些,更好的实现可能如下所示:
function save () {
var imei = document.getElementById('imei').value;
var marca = document.getElementById('marca').value;
var referencia = document.getElementById('referencia').value;
var precio = document.getElementById('precio').value;
var imeiDocRef = db.collection("phone").doc(imei);
db.runTransaction(function(transaction) {
// This code may get re-run multiple times if there are conflicts.
return transaction.get(imeiDocRef).then(function(imeiDoc) {
if (imeiDoc.exists) {
throw `IMEI '${imei}' already exist!`;
}
transaction.set(imeiDocRef, {
Imei: imei,
Marca: marca,
Referencia: referencia,
Precio: precio
});
});
}).then(function() {
console.log("Transaction successfully committed!");
document.getElementById('imei').value = '';
document.getElementById('marca').value = '';
document.getElementById('referencia').value = '';
document.getElementById('precio').value = '';
}).catch(function(error) {
console.log("Transaction failed: ", error);
});
}