Unity iOS构建初始化Firebase Messaging Token事件时崩溃挂起求助
Unity iOS订阅Firebase Messaging事件后启动黑屏挂起问题解决
问题概述
Unity开发的iOS应用构建包在测试时出现启动挂起:Unity启动页正常显示后,首个场景无法加载,仅黑屏,关闭应用弹出崩溃报告。Android版本无此问题,Firebase Cloud Messaging在Android上正常。问题定位到订阅FirebaseMessaging.TokenReceived和MessageReceived事件的代码,移除这两行订阅后应用可正常运行,但通知功能失效。
环境信息:
- Unity版本:2022.3.29(Windows 11构建)
- Firebase SDK版本:12.0.0(曾测试11.6.0)
- 已安装Firebase包:Analytics、Crashlytics、Messaging
- iOS测试设备:iPhone 12 Pro Max(iOS17.4)、iPad 8th Gen(iPadOS17.5),通过TestFlight测试
解决方案
1. 延迟事件订阅,等待Firebase初始化完成
直接在首个场景的Start()中订阅事件,可能Firebase尚未完成初始化,导致线程冲突或未就绪状态引发崩溃。改用协程等待Firebase依赖检查完成后再订阅:
private IEnumerator Start() { // 等待Firebase依赖检查完成 var dependencyTask = Firebase.FirebaseApp.CheckAndFixDependenciesAsync(); yield return new WaitUntil(() => dependencyTask.IsCompleted); if (dependencyTask.Result == Firebase.DependencyStatus.Available) { // 初始化就绪后订阅事件 Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived; Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived; } else { Debug.LogError($"Firebase依赖初始化失败: {dependencyTask.Result}"); } } public void OnTokenReceived(object sender, TokenReceivedEventArgs token) => Debug.Log("Received Registration Token: " + token.Token); public void OnMessageReceived(object sender, MessageReceivedEventArgs e) => Debug.Log("Received a new message from: " + e.Message.From);
2. 调整iOS端Firebase初始化顺序
Unity生成iOS包后,检查Xcode项目中的UnityAppController.mm文件,确保Firebase的初始化代码[FIRApp configure];在Unity初始化逻辑之后执行。避免Firebase在Unity场景加载前触发事件,导致主线程阻塞。
3. 确认iOS推送配置完整性
- 确保Xcode项目的
Signing & Capabilities中已添加Push Notifications权限,以及Background Modes下的Remote notifications选项 - 验证Firebase控制台中APNs密钥/证书与Xcode项目的Team ID、包名完全匹配
- 确保Cocoapods安装的Firebase SDK版本与Unity中使用的版本一致,避免版本不兼容
4. 将事件回调切换至Unity主线程
iOS上Firebase的事件回调可能在后台线程触发,而Unity的场景操作、日志输出等需要在主线程执行。可以实现一个简单的主线程调度器来处理回调:
// 主线程调度器实现 public class UnityMainThreadDispatcher : MonoBehaviour { private static UnityMainThreadDispatcher _instance; private Queue<Action> _actionQueue = new Queue<Action>(); public static UnityMainThreadDispatcher Instance { get { if (_instance == null) { _instance = FindObjectOfType<UnityMainThreadDispatcher>(); if (_instance == null) { var obj = new GameObject("UnityMainThreadDispatcher"); _instance = obj.AddComponent<UnityMainThreadDispatcher>(); DontDestroyOnLoad(obj); } } return _instance; } } private void Update() { lock (_actionQueue) { while (_actionQueue.Count > 0) { _actionQueue.Dequeue().Invoke(); } } } public void Enqueue(Action action) { lock (_actionQueue) { _actionQueue.Enqueue(action); } } } // 修改事件回调 public void OnTokenReceived(object sender, TokenReceivedEventArgs token) { UnityMainThreadDispatcher.Instance.Enqueue(() => { Debug.Log("Received Registration Token: " + token.Token); }); } public void OnMessageReceived(object sender, MessageReceivedEventArgs e) { UnityMainThreadDispatcher.Instance.Enqueue(() => { Debug.Log("Received a new message from: " + e.Message.From); }); }
额外排查建议
- 即使无法访问Mac,可在App Store Connect的
TestFlight->崩溃页面查看崩溃堆栈信息,定位具体崩溃点 - 尝试在代码中显式调用
Firebase.FirebaseApp.InitializeApp(),替代自动初始化逻辑
内容的提问来源于stack exchange,提问作者BrandonN
相关产品推荐
相关产品推荐

