我有一个 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
向数组添加一个新元素,但不会更新我们已有的元素。
我该怎么做?
使用事务防止两个客户端覆盖彼此的更新。您的事务将简单地读取要更新的文档,然后对其进行更改(通过更新数组字段或您想要的任何其他内容)。如果两个客户端最终尝试同时运行事务,其中一个将被迫自动重新运行您的事务处理程序,以帮助您确保不会丢失数据。