Firestore:更新数组的特定元素

问题描述 投票:0回答:1

我有一个 2 人游戏。文档的结构是这样的:

{
 status: string,
 create_by: string,
 players: [
  {
   id: string,
   time: int
  },
  {
   id: string,
   time: int
  } 
 ]
}

要创建会话,我这样做:

Future<String> createGameSession() async {
    final user = AuthProvider().getUser();
    final sessionRef = await _firestore.collection('game_sessions').add({
      'created_by': user.uid,
      'status': 'open',
      'players': [
        {
          'id': user.uid,
        }
      ],
    });
    gameSessionId = sessionRef.id;
    return sessionRef.id;
  }

当第二个玩家加入时:

Future<void> addPlayerGameSession() async {
    final user = AuthProvider().getUser();
    await _firestore.collection('game_sessions').doc(gameSessionId).update({
      'status': 'closed',
      'players': FieldValue.arrayUnion([
        {
          'id': user.uid,
        }
      ]),
    });
  }

在用户界面中,用户可以停止计时器,因此当发生这种情况时,我需要更新文档。这是我无法仅更新我需要的文档的问题。我必须按照文档提到的那样更新整个数组:

更多信息:https://www.reddit.com/r/Firebase/comments/15xeiac/how_to_update_an_item_in_an_array_with_firebase/

我可能会面临这样一种情况:两个用户几乎同时停止计时器,最后一个用户会使用另一个玩家未更新的计时器来更新整个数组,然后再从数据库获取计时器,并且某些信息可以被覆盖。

arrayUnion
向数组添加一个新元素,但不会更新我们已有的元素。

我该怎么做?

firebase google-cloud-firestore
1个回答
0
投票

使用事务防止两个客户端覆盖彼此的更新。您的事务将简单地读取要更新的文档,然后对其进行更改(通过更新数组字段或您想要的任何其他内容)。如果两个客户端最终尝试同时运行事务,其中一个将被迫自动重新运行您的事务处理程序,以帮助您确保不会丢失数据。

© www.soinside.com 2019 - 2024. All rights reserved.