Firebase Database在Unity场景切换时停止工作的问题咨询
我之前也踩过这个坑!Unity场景切换后Firebase Database直接罢工,不管是编辑器还是真机都这样,折腾了好几天才捋清楚问题根源,给你分享几个亲测有效的解决办法:
1. 用全局单例保持Firebase实例不被销毁
场景切换时,承载Firebase初始化逻辑的GameObject很容易被销毁,导致后续场景里没有活跃的Firebase实例。最稳妥的做法是写一个全局单例管理器,让它在场景切换时持续存在:
public class FirebaseManager : MonoBehaviour { public static FirebaseManager Instance { get; private set; } private Firebase.Database.FirebaseDatabase _database; private void Awake() { // 确保单例唯一 if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); // 核心:场景切换不销毁 InitializeFirebase(); } private void InitializeFirebase() { Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => { var dependencyStatus = task.Result; if (dependencyStatus == Firebase.DependencyStatus.Available) { _database = Firebase.Database.FirebaseDatabase.DefaultInstance; Debug.Log("Firebase Database初始化完成"); } else { Debug.LogError($"Firebase依赖加载失败: {dependencyStatus}"); } }); } // 封装Database读写方法,供其他场景调用 public void WriteData(string path, object value) { if (_database == null) { Debug.LogWarning("Firebase Database尚未初始化"); return; } _database.GetReference(path).SetValueAsync(value) .ContinueWithOnMainThread(task => { if (task.IsFaulted) { Debug.LogError($"数据写入失败: {task.Exception}"); } else { Debug.Log("数据写入成功"); } }); } public void ReadData(string path, Action<Firebase.Database.DataSnapshot> onSuccess) { if (_database == null) { Debug.LogWarning("Firebase Database尚未初始化"); return; } _database.GetReference(path).GetValueAsync() .ContinueWithOnMainThread(task => { if (task.IsFaulted) { Debug.LogError($"数据读取失败: {task.Exception}"); } else if (task.IsCompleted) { onSuccess?.Invoke(task.Result); } }); } }
把这个脚本挂在一个空GameObject上,放在第一个加载的场景里,后续场景就不需要再重复初始化Firebase了,直接通过FirebaseManager.Instance调用读写方法即可。
2. 绝对避免重复初始化FirebaseApp
很多人会在每个场景的脚本里单独初始化Firebase,这会导致多个FirebaseApp实例冲突,直接让后续场景的Database失效。
正确的做法是:只在全局单例里初始化一次Firebase,其他场景的脚本直接使用已经初始化好的实例。如果必须做检查,可以加一段判断:
if (Firebase.FirebaseApp.DefaultInstance == null) { Firebase.FirebaseApp.Create(); } var database = Firebase.Database.FirebaseDatabase.DefaultInstance;
不过还是建议完全交给全局单例来处理,避免手动初始化带来的问题。
3. 管理异步任务的生命周期
场景切换时,未完成的Firebase异步回调(比如读写数据的ContinueWith)可能会因为原脚本被销毁而失效,导致后续操作无响应。
解决办法就是所有Firebase异步操作都通过全局单例发起,这样即使场景切换,回调依然会在单例对象上执行,不会因为原场景脚本被销毁而丢失。比如上面单例里封装的WriteData和ReadData方法,就是把回调绑定在单例的生命周期上。
4. 检查依赖状态的持续性
偶尔会出现场景切换后Firebase依赖状态异常的情况,可以在单例的OnEnable方法里重新检查依赖,确保状态正常:
private void OnEnable() { Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => { if (task.Result != Firebase.DependencyStatus.Available) { Debug.LogWarning("Firebase依赖状态异常,重新初始化"); InitializeFirebase(); } }); }
按照上面的方法调整后,场景切换时Firebase Database应该就能正常工作了,我自己就是这么解决的。
内容的提问来源于stack exchange,提问作者user3370178

