android - 如何更新事务中的多个节点(Firebase 实时数据库)
问题描述
对于以下数据库示例结构:
{
"stats": {
"posts_count": 231,
"posts_by_category": {
"sports": {
"count": 12,
"foo": "bar"
}
},
"posts_by_language": {
"english": {
"count": 12,
"foo": "bar"
}
}
}
}
并且给定 [english, sports] 类别中的新帖子,我如何运行具有以下更改的事务:
stats/posts_count +1
stats/posts_by_category/sports/count +1
stats/posts_by_language/english/count +1
基本上我不知道如何导航/编辑 MutableData 对象以反映更改,我想要一个示例(最好不使用 DAO 类)
db.getReference("stats").runTransaction(object : Transaction.Handler {
override fun doTransaction(currentData: MutableData): Transaction.Result {
????
return Transaction.success(currentData)
}
override fun onComplete(
error: DatabaseError?,
committed: Boolean,
currentData: DataSnapshot?
) {
}
})
解决方案
事务在单个节点上运行。因此,如果您想以事务方式更新数据库中的多个分支,则必须在最低的公共祖先节点上运行单个事务。在你的例子中是stats
. 请注意,这可能会在写操作上产生很多争用。如果stats
节点可能在同一时间被许多客户端更新,这可能会导致多次重试并可能导致事务失败。
不过,在您的示例中,您似乎想要增加计数器,Firebase 实时数据库自今年早些时候以来将其作为本机操作支持。stats
因此,我不会在 上运行事务,而是对其运行以下更新操作:
Map<String, Object> updates = new HashMap<>();
updates.put("posts_count", ServerValue.increment(1));
updates.put("posts_by_category/sports/count", ServerValue.increment(1));
updates.put("posts_by_language/english/count", ServerValue.increment(1));
db.getReference("stats").updateChildren(updates);
这里需要注意的事项:
- 这里
/
的键是一个特殊的符号,允许更新嵌套的属性。 - 将
ServerValue.increment(1)
作为标记发送到数据库,然后由数据库自动执行。
推荐阅读
- javascript - 剃须刀页面 html 选择下拉列表未绑定到模型且 javascript 看不到
- angular - 如何将 HTTP API 中的对象列表映射到字符串列表?
- pandas - 过滤熊猫列
- python - 如何识别图像的蒙版/边缘检测是圆形还是椭圆形?
- html - 用于 YouTube 嵌入的 iframe:延迟加载在 Firefox 中不起作用
- c# - 使用 Xamarin 进行 OCR
- android - 如何在 Android 中获取 FrameLayout 的 XY 坐标?
- python - 尝试按照 python 中的教程进行操作,但我不断收到此错误 - istart = _int(start) TypeError: 'str' object is not callable
- java - 如果我想在 JavaFX 中调整 ImageView 的大小以仅适合边框的整个左侧区域而不调整到其他区域的大小?
- flutter - 如何创建偏移滑出对话框叠加