如何更新事务中的多个节点(Firebase实时数据库)

时间:2020-10-16 17:14:15

标签: android firebase kotlin firebase-realtime-database

对于以下数据库示例结构:

  {
    "stats": {
      "posts_count": 231,
      "posts_by_category": {
        "sports": {
          "count": 12,
          "foo": "bar"
        }
      },
      "posts_by_language": {
        "english": {
          "count": 12,
          "foo": "bar"
        }
      }
    }
  }

在[英语,体育]类别中有一篇新帖子,如何进行以下更改来进行交易:

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?
    ) {
    }
})

谢谢

1 个答案:

答案 0 :(得分:0)

事务在单个节点上运行。因此,如果要以事务方式更新数据库中的多个分支,则必须在最低的公共祖先节点上运行单个事务。在您的示例中,该名称为stats。请注意,这可能在写操作上引起很多争用。如果stats节点可能由许多客户端在同一时间更新,则可能导致许多重试,并且可能导致事件失败。

但是在您的示例中,您似乎想增加计数器,自今年早些时候以来,Firebase Realtime Database作为本机操作支持该计数器。因此,我没有在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)作为标记发送到数据库,然后由数据库自动执行。