我在firebase实时数据库中有一个集合,该集合是一个代码库,每个“商店”都可以使用一次。我需要搜索未使用的代码,然后以原子方式将其标记为由商店保留。问题是我不知道如何在firebase中进行事务搜索和更新,并且未使用的代码被“使用”多次,直到更新为止。
const getUnusedCode = (storeID) => {
const codeRef = rtdb.ref('codes');
return codeRef
.orderByChild(storeID)
.equalTo(null)
.limitToFirst(1)
.once('child_added')
.then(snap => {
//setting the map {[storeID]:true} reserves the code
return snap.ref.update({ [storeID]: true }).then(() => {
return snap.key;
});
});
};
编辑:这是“代码”集合的结构:
{
"-LQl9FFD39PAeN5DnrGE" : {
"code" : 689343821901,
"i" : 0,
"5s6EgdItKW7pBIawgulg":true,
"ZK0lFbDnXcWJ6Gblg0tV":true,
"uKbwxPbZu2fJlsn998vm":true
},
"-LQl9FOxT4eq6EbwrwOx" : {
"code" : 689343821918,
"i" : 1,
"5s6EgdItKW7pBIawgulg":true
},
"-LQl9FPaUV33fvkiFtv-" : {
"code" : 689343821925,
"i" : 2
},
"-LQl9FQEwKKO9T0z4LIP" : {
"code" : 689343821932,
"i" : 3,
"ZK0lFbDnXcWJ6Gblg0tV":true
},
"-LQl9FQsEVSNZyhgdHmI" : {
"code" : 689343821949,
"i" : 4,
"5s6EgdItKW7pBIawgulg":true,
"uKbwxPbZu2fJlsn998vm":true
}
}
在此数据中,“ 5s6EgdItKW7pBIawgulg”是商店ID,为true表示此代码已用于该商店
当导入新项目时,此函数可能每分钟被调用数百次,并且由于不是原子搜索然后更新,因此会返回重复项。在Firebase中有可能吗?
答案 0 :(得分:1)
据我了解,您具有这样的结构
codes: {
"code1": {
storeid: "store1"
},
"code2": {
storeid: "store2"
}
}
您正在尝试按商店进行交易更新。
如果这是您要执行的唯一更新,强烈建议您反转数据结构:
codes: {
"store1": "code1",
"store2": "code2"
}
在这种结构下,商店的交易非常简单,因为路径是已知的:
var storeRef = firebase.database().ref("codes").child("store1");
storeRef.transation(function(current) {
if (current) {
// remove the code from the database
return null;
}
else {
// abort the transaction, since the code no longer exists
return undefined;
}
});
如果您无法更改数据结构,我可能会使用您当前的代码来找到代码的DatabaseReference
,然后在回调中使用事务进行更新:
codeRef
.orderByChild(storeID)
.equalTo(null)
.limitToFirst(1)
.once('child_added')
.then(snap => {
//setting the map {[storeID]:true} reserves the code
return snap.ref.transaction(function(current) {
if (!current || current[storeId]) {
// the node no longer exists, or it already was claimed for this store
return undefined; // abort the transaction
}
else {
current[storeId] = true;
return current;
}
})
});