【问题标题】:firebase realtime database transaction cause listener callback with data that not committedfirebase 实时数据库事务导致监听器回调与未提交的数据
【发布时间】:2021-10-07 17:22:35
【问题描述】:

我正在使用适用于 android 的 firebase 实时数据库,进行事务以更新对象,假设阻止 2 个用户相互覆盖。这似乎有效。

问题:一位用户被阻止写信,所以doTransation() 将被再次调用。 根据我下面的逻辑,第一个 doTransation 调用不会在服务器上生效。第二个 doTransation 调用将中止。 在第一个 doTransation 之后和第二个之前,我将回调 onDataChange() 到我的 ValueEventListener,其中包含被拒绝/未提交的数据以及在调用 onComplete() 之前。

知道为什么会出现这种行为吗?怎么改?

fun onIconClicked(currentGameState: GameState, gameId: String, iconClicked: Long) {
    Log.d(TAG, "onIconClicked() called")

    database.child(GAME_STATE_PATH).child(gameId).runTransaction(object : Transaction.Handler {
        override fun doTransaction(currentData: MutableData): Transaction.Result {

            val gameState = currentData.getValue(GameState::class.java)
                ?: return Transaction.success(currentData)

            // make sure the state from server match the client, and check if won the card        
            return if (gameState == currentGameState && true == currentGameState.users?.get(currentUserId)?.card?.contains(iconClicked) &&
                    true == currentGameState.mainCard?.contains(iconClicked)) {

                // player won card - make the changes in game state...

                currentData.value = gameState
                Log.d(TAG, "doTransaction() winning card, game after = $gameState")

                Transaction.success(currentData)
            } else {
                Log.d(TAG, "doTransaction() aborting")
                Transaction.abort()
            }
        }

        override fun onComplete(error: DatabaseError?, committed: Boolean, currentData: DataSnapshot?) {
            Log.d(TAG, "onIconClicked onComplete() called with: error = $error, committed = $committed, currentData = $currentData")
        }
    })
}

【问题讨论】:

  • 请编辑您的问题并添加 Frank van Puffelen 要求的信息,并回复@。
  • @AlexMamo 已添加,谢谢!
  • 所以您收到错误消息?那条信息是什么?
  • @AlexMamo 没有错误。尝试执行事务但未提交任何内容的客户端通过侦听器获取未提交的数据。请再次阅读我的问题

标签: android firebase firebase-realtime-database


【解决方案1】:

我收到了回调 onDataChange() 到我的 ValueEventListener,其中包含在 onComplete() 调用之前被拒绝/未提交的数据。

事务运行所在的同一客户端上的侦听器确实会看到中间事务迭代的本地事件。

如果您不希望触发这些本地事件,请使用 runTransaction 的重载,它接受名为 fireLocalEvents 的第二个参数,并为此传递 false

所以:

database.child(GAME_STATE_PATH).child(gameId).runTransaction(..., false)

【讨论】:

  • 谢谢!似乎 false 应该是默认值而不是 true 或者根本没有默认值。请考虑将其添加到基本使用文档中,因为我在任何地方都找不到它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 1970-01-01
  • 2019-05-15
  • 2021-11-23
相关资源
最近更新 更多