Firebase导致Unity编辑器重进播放模式卡死相关问题咨询
问题解答
问题1:操作是否存在错误,重进播放模式卡死是否合理
你的代码存在两处核心错误,卡死是完全符合错误逻辑的:
- 异步时序错误:
CheckAndFixDependenciesAsync是异步方法,你在Start里同步执行db = FirebaseFirestore.DefaultInstance时,依赖检查还未完成,Firebase还未进入可用状态,此时获取实例会触发未定义行为。 - 编辑器域重载兼容问题:Unity编辑器退出播放模式时,默认不会自动销毁Firebase的native层实例,你主动将
FirebaseApp.DefaultInstance赋值给类字段app时,相当于托管层额外持有了该实例的引用,退出播放模式时该引用没有被主动释放,第二次进入播放模式重新初始化Firebase时,native层和托管层的实例状态冲突,直接触发死锁导致编辑器卡死。你注释掉赋值行后,托管层没有额外持有引用,Firebase内部的引用管理逻辑可以正常处理实例的状态同步,因此不会触发卡死。
修复建议可以参考如下代码实现:
Firebase.FirebaseApp app; FirebaseFirestore db; bool isFirebaseReady = false; void Start() { Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => { var dependencyStatus = task.Result; if (dependencyStatus == Firebase.DependencyStatus.Available) { app = Firebase.FirebaseApp.DefaultInstance; db = FirebaseFirestore.DefaultInstance; isFirebaseReady = true; Debug.Log("Firebase初始化成功"); } else { UnityEngine.Debug.LogError($"Could not resolve all Firebase dependencies: {dependencyStatus}"); } }); } void OnDestroy() { // 退出场景/播放模式时主动释放实例,解决编辑器重载冲突 app?.Dispose(); }
问题2:官方建议存储FirebaseApp变量的原因
- 防止GC意外回收:
FirebaseApp.DefaultInstance是托管层对native层实例的包装对象,如果你全程只通过静态属性访问,没有主动持有引用,极端情况下GC可能会将托管层的包装对象判定为未使用而回收,导致底层native实例被提前释放,后续调用相关API会抛出空引用或native错误。 - 多实例场景兼容:如果你的项目需要同时对接多个Firebase项目(比如测试环境和生产环境分离),每个项目对应一个独立的
FirebaseApp实例,持有变量可以明确区分不同实例,避免混淆默认实例。 - 性能优化:每次调用
DefaultInstance属性都会做一次实例存在性检查,主动持有引用可以减少不必要的检查开销,属于官方推荐的通用最佳实践。
如果你只用到Firestore单实例场景,Firestore内部已经持有了对应的FirebaseApp引用,所以你不主动存储也不会出现问题,和你注释掉代码后运行正常的表现一致。
内容的提问来源于stack exchange,提问作者rustyBucketBay
相关产品推荐
相关产品推荐

