App集成Firebase推送后无声音与角标,如何通过UserNotifications处理?
解决Firebase推送无提示音与角标的问题
你完全找对方向了!要解决提示音和角标的问题,确实需要借助UserNotifications框架来接管通知的展示逻辑,同时配合Firebase的配置来确保推送payload包含必要的字段。下面是一步步的具体操作:
1. 确保基础配置到位
首先检查两个关键配置:
- 项目Capabilities中已开启Push Notifications
- Background Modes中勾选了Remote notifications
- 推送权限请求时必须包含声音和角标权限(这是很多人忽略的点)
2. 导入必要框架并设置代理
在你的AppDelegate(或SceneDelegate,取决于iOS版本)中导入框架,并设置通知中心和Firebase Messaging的代理:
import UIKit import Firebase import FirebaseMessaging import UserNotifications @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 初始化Firebase FirebaseApp.configure() // 请求完整的推送权限:必须包含.alert、.sound、.badge UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in guard granted, error == nil else { print("推送权限请求失败或被拒绝") return } DispatchQueue.main.async { // 注册远程通知 application.registerForRemoteNotifications() } } // 设置通知中心代理,用于处理通知展示逻辑 UNUserNotificationCenter.current().delegate = self // 设置Firebase Messaging代理,处理token和后台通知 Messaging.messaging().delegate = self return true } }
3. 实现UNUserNotificationCenterDelegate处理通知展示
通过代理方法控制前台/后台通知的展示行为,同时处理角标和提示音:
extension AppDelegate: UNUserNotificationCenterDelegate { // 前台收到通知时的处理逻辑 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { // 指定展示选项:必须包含.sound和.badge才会触发提示音和角标更新 completionHandler([.alert, .sound, .badge]) // 手动更新应用角标(可选,也可以依赖payload中的badge字段自动处理) if let badgeCount = notification.request.content.badge as? Int { UIApplication.shared.applicationIconBadgeNumber = badgeCount } } // 用户点击通知后的处理逻辑 func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { // 点击通知后可以清空角标 UIApplication.shared.applicationIconBadgeNumber = 0 // 这里可以添加跳转页面等业务逻辑 completionHandler() } }
4. 处理Firebase后台通知与角标更新
实现MessagingDelegate并处理后台收到通知的场景:
extension AppDelegate: MessagingDelegate { // 获取FCM Token的回调(可选,用于向特定设备推送) func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { print("FCM Token: \(fcmToken ?? "")") // 可以将Token上传到你的服务器 } // 后台收到远程通知时的处理 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { // 从推送payload中提取badge数并更新 if let badgeCount = userInfo["badge"] as? Int { UIApplication.shared.applicationIconBadgeNumber = badgeCount } completionHandler(.newData) } }
5. 确保Firebase推送Payload包含必要字段
在Firebase控制台发送通知时,必须确保payload包含sound和badge字段:
- 进入高级选项 -> 自定义数据
- 添加
aps字段,格式为JSON:
或者直接在控制台的通知标签页中找到角标选项,设置数字,同时确保声音选项开启。{ "aps": { "alert": "你的通知内容", "sound": "default", // 使用系统默认提示音,也可以指定自定义声音文件名 "badge": 1 // 角标数量 } }
关键注意事项
- 如果使用自定义提示音,需要将音频文件(如
custom_sound.wav)添加到项目中,并在payload的sound字段指定文件名 - 角标数可以通过服务器推送时动态设置,也可以在客户端根据业务逻辑调整
- iOS 15+ 对通知权限的请求逻辑有更严格的限制,确保在合适的时机请求权限(比如用户主动触发时)
内容的提问来源于stack exchange,提问作者Agung
相关产品推荐
相关产品推荐

