假设我有一个带有“用户”节点和“宠物”节点的项目。当用户获得宠物时,我想将宠物的密钥添加到用户的“宠物”节点,并将用户ID添加到宠物的“所有者”节点。
示例:
{
"users":{
"user1":{
"pets":{
"pet1":true,
"pet3":true
}
...
}
},
"pets":{
"pet1":{
"owner":"user1",
...
},
...
}
}
我想确保两次更新都能成功阻止状态不一致。
我读到了如何使用Firebase事务here,但是当我尝试创建修改相关值的事务时(使用dbRef.runTransaction(...)),我收到此DatabaseError错误:< / p>
交易重试次数太多
当我在我修改的特定节点上调用runTransaction()时,事务似乎才有效(例如,调用
dbRef.child("users").child("user1").runTransaction(...));
然而,这对我没有帮助,因为我需要联系相关用户和宠物。 如何使此交易有效?
答案 0 :(得分:5)
根据Firebase Docs,您不需要使用交易操作(我稍后会解释)。
为了在 ONE PACKET 的多个节点中保存数据,我建议您构建一个 Map&lt;&gt; 数组,其中键表示路径, Value 表示您想要存储的内容。
假设“user1”刚刚成为“pet4”的所有者,并且您的dbRereference指向根目录:
FirebaseDatabase dbRef = FirebaseDatabase.getInstance().getReference();
Map<String, Object> update = new HashMap<>();
update.put("users/user1/pets/pet4", true);
update.put("pets/pet4/owner", "user4");
稍后您可以运行 .updateChildren(Map&lt;,&gt;)并附加一个监听器。
dbRef.updateChildren(update).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful())
Log.d("Success!");
else
Log.d("Failure");
}
});
通过这种方式,如果发生故障,您的数据库将根本不会被更改。
“交易”是Firebase为不同操作提供的术语,我认为这是导致您混淆的原因:在处理可能被并发修改(例如增量计数器)损坏的数据时使用它。如需进一步阅读,请打开开头附带的链接。