iOS App集成@react-native-firebase/messaging后Release模式启动崩溃
iOS Release模式启动崩溃问题排查与解决
问题描述
安装@react-native-firebase/messaging库后,Debug模式运行正常,但iOS设备安装Release包后启动即崩溃。Xcode中运行Release模式时抛出异常:
Exception NSException * "-[GUL_AppDelegate-57E40680-A962-46D9-8F1B-8F443EF66362 application:didRegisterForRemoteNotificationsWithDeviceToken:]: unrecognized selector sent to instance 0x28362e880" 0x0000000282d1af70
项目依赖
"dependencies": { "@notifee/react-native": "^7.0.1", "@react-native-async-storage/async-storage": "^1.18.1", "@react-native-community/netinfo": "^9.3.10", "@react-native-firebase/app": "^18.1.0", "@react-native-firebase/messaging": "^18.1.0", "@react-navigation/bottom-tabs": "^6.5.7", "@react-navigation/native": "^6.1.6", "@react-navigation/stack": "^6.3.16", "axios": "^1.4.0", "inversify": "^6.0.1", "mime": "^3.0.0", "moment": "^2.29.4", "moment-timezone": "^0.5.43", "react": "18.2.0", "react-native": "0.72.1", "react-native-check-box": "^2.1.7", "react-native-country-picker-modal": "^2.0.0", "react-native-date-picker": "^4.2.13", "react-native-document-picker": "^9.0.1", "react-native-elements": "^3.4.3", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "^2.9.0", "react-native-get-random-values": "^1.8.0", "react-native-indicators": "^0.17.0", "react-native-keyboard-aware-scroll-view": "^0.9.5", "react-native-localize": "^3.0.0", "react-native-material-ripple": "^0.9.1", "react-native-navigation-bar-color": "^2.0.2", "react-native-paper": "^5.8.0", "react-native-safe-area-context": "^4.5.1", "react-native-screens": "^3.20.0", "react-native-vector-icons": "^9.2.0", "react-native-webview": "^12.0.2", "reflect-metadata": "^0.1.13", "rn-emoji-keyboard": "^1.5.0", "rxjs": "^7.8.1", "socket.io-client": "2.4.0", "uuid": "^9.0.0" },
Podfile配置
# Resolve react_native_pods.rb with node to allow for hoisting require Pod::Executable.execute_command('node', ['-p', 'require.resolve( "react-native/scripts/react_native_pods.rb", {paths: [process.argv[1]]}, )', __dir__]).strip platform :ios, min_ios_version_supported prepare_react_native_project! # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded # # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` # ```js # module.exports = { # dependencies: { # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), # ``` flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled linkage = ENV['USE_FRAMEWORKS'] if linkage != nil Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green use_frameworks! :linkage => linkage.to_sym end use_modular_headers! target 'BotPenguinReactNativeMobile' do config = use_native_modules! use_frameworks! :linkage => :static $RNFirebaseAsStaticFramework = true # Flags change depending on the env values. flags = get_default_flags() use_react_native!( :path => config[:reactNativePath], # Hermes is now enabled by default. Disable by setting this flag to false. :hermes_enabled => flags[:hermes_enabled], :fabric_enabled => flags[:fabric_enabled], # Enables Flipper. # # Note that if you have use_frameworks! enabled, Flipper will not work and # you should disable the next line. #:flipper_configuration => flipper_config, # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/.." ) post_install do |installer| # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 react_native_post_install( installer, config[:reactNativePath], :mac_catalyst_enabled => false ) __apply_Xcode_12_5_M1_post_install_workaround(installer) end end
AppDelegate代码
#import "AppDelegate.h" #import <React/RCTBundleURLProvider.h> #import <Firebase.h> @implementation AppDelegate - (void)applicationDidBecomeActive:(UIApplication *)application { [UIApplication sharedApplication].applicationIconBadgeNumber = 0; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [FIRApp configure]; self.moduleName = @"BotPenguinReactNativeMobile"; // You can add your custom initial props in the dictionary below. // They will be passed down to the ViewController used by React Native. self.initialProps = @{}; return [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { return [super application:application didFailToRegisterForRemoteNotificationsWithError:error]; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } @end
解决方案
1. 修复AppDelegate方法调用逻辑
异常核心是GUL_AppDelegate实例无法识别指定方法,原因是Release模式下super相关方法被优化移除,或Firebase代理替换逻辑冲突。直接调用Firebase原生处理逻辑,替换AppDelegate中的远程通知方法:
// 替换远程通知注册成功方法 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [[FIRMessaging messaging] setAPNSToken:deviceToken type:FIRMessagingAPNSTokenTypeProd]; } // 替换远程通知注册失败方法 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"远程通知注册失败: %@", error); } // 替换远程通知接收方法 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; completionHandler(UIBackgroundFetchResultNewData); }
2. 调整Podfile静态框架配置
确保Firebase库以静态框架链接,避免Release模式下符号丢失:
- 将
use_frameworks! :linkage => :static和$RNFirebaseAsStaticFramework = true移至target块外,保证全局生效 - 移除target内重复的
use_frameworks!配置
修改后的关键配置片段:
use_modular_headers! use_frameworks! :linkage => :static $RNFirebaseAsStaticFramework = true target 'BotPenguinReactNativeMobile' do config = use_native_modules! flags = get_default_flags() use_react_native!( :path => config[:reactNativePath], :hermes_enabled => flags[:hermes_enabled], :fabric_enabled => flags[:fabric_enabled], :app_path => "#{Pod::Config.instance.installation_root}/.." ) # 其余配置保留不变 end
3. 清理重建项目
- 执行命令清理依赖:
cd ios && pod deintegrate && pod install - 在Xcode中清理构建缓存:
Cmd + Shift + K - 重新生成Release安装包
4. 关闭Release模式死代码剥离
在Xcode Build Settings中,防止Firebase方法被误删:
- 打开Xcode项目,选择目标target
- 进入Build Settings,搜索
Dead Code Stripping - 将Release模式下的值设置为
NO
内容的提问来源于stack exchange,提问作者Rajat Kumar
相关产品推荐
相关产品推荐

