我正在 Flutter 中使用 Firestore 构建多人游戏来处理实时更新。我需要解决的情况之一是玩家完全终止应用程序。在这种情况下,应更新 Firestore 以将玩家从活动方中删除。
我尝试通过使用 Firebase 云功能来实现此目的,该功能可侦听 Firebase 实时数据库中玩家的在线状态。当玩家的在线状态更改为 {online: false} 时,Cloud Function 会更新 Firestore 并将玩家从队伍中删除。
我面临的问题是,当应用程序完全终止时,我无法可靠地更改 Firebase 实时数据库中的玩家状态。每当应用程序的生命周期状态发生变化时,我都会调用以下方法:
void updatePresenceOnAppState(
AppLifecycleState state,
String partyId,
String playerId,
) {
print(state);
final presenceRef = _database
.ref()
.child('party-presence')
.child(partyId)
.child(playerId);
if (state == AppLifecycleState.paused || state == AppLifecycleState.inactive) {
presenceRef.set({'online': true, 'state': 'background'});
} else if (state == AppLifecycleState.detached) {
presenceRef.set({'online': false, 'state': 'terminated'});
} else if (state == AppLifecycleState.resumed) {
presenceRef.set({'online': true, 'state': 'active'});
}
}
但是,AppLifecycleState.detached 似乎无法在应用程序终止时可靠地将在线状态设置为 false。这会导致即使应用程序关闭后,玩家的状态仍保持为“在线”。
是否有可靠的方法来检测 Flutter 中的应用程序完全终止,以更新 Firebase 实时数据库中玩家的在线状态?或者是否有推荐的方法来处理玩家终止事件以触发必要的 Firestore 更新?
我尝试使用 AppLifecycleState.detached 来检测应用程序何时完全终止。我的期望是,在 AppLifecycleState.detached 内的 Firebase 实时数据库中设置 {online: false, state: 'termerated'} 能够可靠地将玩家标记为离线,然后触发我的 Cloud Function 将玩家从 Firestore 中的聚会中删除。
实际发生了什么:
相反,当应用程序终止时,AppLifecycleState.detached 似乎不会一致地更新 Firebase 实时数据库,即使在关闭应用程序后,玩家的状态仍为“在线”。这意味着云功能不会运行,并且玩家不会按预期从聚会中删除。
当应用完全终止时,我无法可靠地更改 Firebase 实时数据库中的玩家状态
这是预料之中的。当应用程序终止时,没有保证可以在应用程序内部运行代码。一个简单的例子说明了为什么这是不可能的:应用程序崩溃时:因为发生这种情况时您的代码无法继续运行。
解决方案是使用 Firebase 实时数据库的内置。这使用客户端和服务器端代码的组合来检测客户端何时断开连接。该文档甚至还提供了一个完整的、经过实战考验的存在系统的示例。 如果您在应用程序中实现此功能,则客户端断开连接时发生的写入/删除操作将在服务器上执行,然后也会反映在您的 Firestore 数据库中。