Flutter iOS使用awesome_notifications时无notification对象推送不显示问题
解决iOS端纯Data推送不显示自定义通知的问题
1. 先明确iOS APNs的推送规则
iOS的APNs对推送类型有严格区分:
- 带
notification(或aps.alert)的推送:APNs直接接管通知展示,不管App处于前台、后台还是被杀死状态,都能直接显示默认通知。 - 纯
data推送:只有App处于前台活跃状态时,Firebase Messaging才会触发onMessage回调;App后台或被杀死时,APNs不会主动触发回调,也不会显示任何通知。
如果要在App后台/杀死状态下处理纯Data推送并展示自定义来电通知,必须通过静默推送配置,同时在Flutter端监听回调并手动创建通知。
2. 调整Payload格式
需要在Payload中添加aps对象,配置content-available: 1来触发静默推送,同时保留data字段传递来电信息。注意:静默推送的aps不能包含alert、sound等会触发默认通知的字段,否则会显示系统默认通知。
示例Payload:
{ "registration_ids": [ "XXXEW23232332323232332oES-xeLNriKi_kds19eB6p9liZfl7pkJ8WWHh45G8VwJLH6-DK3bd7lRCGWQ_" ], "aps": { "content-available": 1 }, "data": { "fromName": "Nosa", "messageType": "VOICE_CALL", "message": "What do you think", "fromUserId": "09034286339" } }
3. Flutter端配置与监听逻辑
(1)配置后台消息处理器
设置FirebaseMessaging.onBackgroundMessage,用来处理App后台/杀死状态下的静默推送回调,在回调中用awesome_notifications创建自定义来电通知:
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); final data = message.data; // 只处理来电类型的推送 if (data['messageType'] == 'VOICE_CALL') { await AwesomeNotifications().createNotification( content: NotificationContent( id: 10, channelKey: 'voice_call_channel', // 需提前创建对应的通知渠道 title: '来电提醒', body: '来自${data['fromName']}的语音通话', wakeUpScreen: true, fullScreenIntent: true, // 来电需全屏展示,iOS需额外配置权限 category: NotificationCategory.Call, ), actionButtons: [ NotificationActionButton( key: 'ACCEPT_CALL', label: '接听', actionType: ActionType.Default, ), NotificationActionButton( key: 'REJECT_CALL', label: '拒绝', actionType: ActionType.Default, ), ], ); } }
(2)初始化阶段注册处理器与配置
在main函数中完成Firebase、awesome_notifications的初始化,并注册后台处理器:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // 注册后台消息处理器 FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); // 初始化awesome_notifications并创建来电渠道 await AwesomeNotifications().initialize( null, [ NotificationChannel( channelKey: 'voice_call_channel', channelName: '语音通话', channelDescription: '处理来电通知', importance: NotificationImportance.Max, defaultRingtoneType: DefaultRingtoneType.Ringtone, locked: true, // 锁定通知,防止用户滑动清除 ) ], ); runApp(MyApp()); }
(3)iOS端额外配置
- 添加后台模式权限:打开
ios/Runner/Info.plist,加入以下内容:<key>UIBackgroundModes</key> <array> <string>remote-notification</string> </array> - 申请全屏通知权限:修改
ios/Runner/AppDelegate.swift,添加权限请求代码:import UIKit import Flutter import FirebaseMessaging import AwesomeNotifications @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { FirebaseApp.configure() // 请求包含全屏intent的通知权限 UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound, .fullScreenIntent]) { granted, error in if granted { DispatchQueue.main.async { application.registerForRemoteNotifications() } } } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }
4. 关键注意事项
- 静默推送的
content-available: 1必须正确设置,否则App后台/杀死状态下不会触发回调。 - iOS对静默推送的频率有限制,请勿频繁发送,否则可能被APNs限流。
- 测试后台推送时,必须将App退到后台或完全杀死,前台状态下会走
onMessage回调而非后台处理器。 - 确保
awesome_notifications的通知渠道配置正确,且用户已授权通知权限。
内容的提问来源于stack exchange,提问作者Zionnite
相关产品推荐
相关产品推荐

