我一直在很好地使用 firestore 事务,并一直在尝试实现一些 RTDB 版本。我有一棵带有自动生成键的树。这些键的值是映射,其中一个键是“uid”,例如"AUTOGENKEY" : { "uid" : 'a uid'}, ...etc我想要一个可以删除所有单身用户节点的事务...如果用户在事务期间创建了任何新节点,它应该重试并将新节点包含在事务删除中。我目前有这个await rtdb.ref(‘someRef’) .orderByChild(‘uid’) .equalTo(uid) .once('value') .transaction(function(currentVal) { // Loop each of the nodes with a matching ‘uid’ and delete them // If any of the nodes are updated (or additional nodes are created with matching uids) // while the transaction is running it should restart and retry the delete // If no nodes are matched nothing should happen });但是我想仔细检查我是否需要在 currentVal 回调中进行另一个事务,以及我是否可以只返回 null 来删除每个节点。我一直在使用这个答案作为参考Firebase 数据库事务搜索和更新亲切的问候- 编辑新方法坦率地说,我听取了您的建议,最终只是像这样存储我的数据:uid -> counter 我不知道交易不能在查询中运行,谢谢你让我知道。我需要能够从 uid 计数中添加/减去数量,如果它导致数字低于 0,则应删除该节点。如果我将 null 作为数量传递,它应该删除该节点。这就是我目前拥有的。async function incrementOrDecrementByAmount(pathToUid, shouldAdd, amount, rtdb){ await rtdb.ref(pathToUid) .transaction(function(currentVal) { if(currentVal == null || amount == null) { return amount; }else{ let newAmount = null; // Just sum the new amount if(shouldAdd == true) { newAmount = currentVal + amount; } else { const diff = currentVal - amount; // If its not above 0 then leave it null so it is deleted if(newAmount > 0) { newAmount = diff; } } return newAmount; } });}如果我有以下执行,我不确定第一个 if 语句。incrementOrDecrementByAmount (somePath, 10, true, rtdb)incrementOrDecrementByAmount (somePath, 100, false, rtdb)这总是会导致节点被删除吗?交易是否始终取决于调用顺序,或者它是关于谁先完成的竞争条件。
1 回答
ITMISS
TA贡献1871条经验 获得超8个赞
事务只能在 a 上运行DatabaseReference,而不能在 上运行Query。因此,在您的情况下,您将必须在完整someRef节点上运行事务,然后修改currentVal以删除属性与您的条件匹配的节点uid。
如果有很多uid值,这可能会导致读取比需要的数据多得多的数据,如果多个用户可能同时执行此操作,这可能会导致争用和重试。在这种情况下,请考虑另一种数据结构,它允许您运行更独立的事务,例如通过将每个uid值的节点存储在该值下作为键。
someRef: {
"uid1": {
...
},
"uid2": {
...
}
}
使用这样的结构,uid可以通过简单的单个写入操作来删除单个值的所有值。
添加回答
举报
0/150
提交
取消