iOS应用能否仅显示Firebase远程推送角标而不展示通知弹窗?
Firebase iOS 推送:仅显示角标不触发通知弹窗的实现方案
没问题,这个需求完全可以实现!Firebase Cloud Messaging(FCM)配合iOS的APNs机制,能够做到应用未运行时只更新图标角标、不弹出通知弹窗,核心是通过调整推送Payload配置+少量客户端代码配合完成。
核心原理
当应用未处于前台/后台运行状态时,iOS系统会直接处理APNs推送请求。如果我们不想让系统展示通知弹窗,只需要在推送的Payload里移除所有alert相关字段(包括title、body等),同时指定badge字段的数值即可。FCM会将这个合规的Payload转发给APNs,系统就只会更新应用图标角标,不会触发通知弹窗。
1. 配置FCM推送Payload
不管你是通过Firebase控制台发送推送,还是调用FCM API,都需要构造正确的Payload:
- 必须移除
alert、title、body等所有和通知弹窗相关的字段 - 添加
badge字段,设置你想要显示的角标数字(比如1表示直接设为1,或者你也可以在客户端处理增量逻辑)
FCM API Payload示例
{ "to": "目标设备的FCM Token", "aps": { "badge": 1 } }
Firebase控制台操作步骤
在控制台发送推送时:
- 不要填写「通知标题」和「通知内容」
- 切换到「高级选项」,添加自定义键值对:
- 键名填
aps,值类型选择「Map」 - 在
aps的Map下添加键badge,值设为你需要的数字
- 键名填
2. iOS客户端代码处理(Swift)
虽然主要依赖Payload配置,但你可能需要处理角标的重置逻辑(比如用户打开应用后清除角标),同时确保只请求必要的推送权限:
import UIKit import FirebaseMessaging import UserNotifications @main class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { FirebaseApp.configure() Messaging.messaging().delegate = self // 仅请求角标权限,不需要alert权限 UNUserNotificationCenter.current().requestAuthorization(options: [.badge]) { granted, error in guard granted else { return } DispatchQueue.main.async { application.registerForRemoteNotifications() } } return true } // 应用激活时清除角标 func applicationDidBecomeActive(_ application: UIApplication) { UIApplication.shared.applicationIconBadgeNumber = 0 } }
3. iOS客户端代码处理(Objective-C)
Objective-C版本的对应实现:
#import "AppDelegate.h" #import <Firebase/Firebase.h> #import <UserNotifications/UserNotifications.h> @interface AppDelegate () <UNUserNotificationCenterDelegate, FIRMessagingDelegate> @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [FIRApp configure]; [FIRMessaging messaging].delegate = self; // 仅申请角标推送权限 [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionBadge completionHandler:^(BOOL granted, NSError * _Nullable error) { if (granted) { dispatch_async(dispatch_get_main_queue(), ^{ [application registerForRemoteNotifications]; }); } }]; return YES; } // 应用进入前台时清除角标 - (void)applicationDidBecomeActive:(UIApplication *)application { [UIApplication sharedApplication].applicationIconBadgeNumber = 0; } @end
关键注意事项
- 确保你的iOS应用已经正确配置了APNs证书和Firebase推送环境,这是所有推送功能生效的基础
- 一定要确认Payload里没有任何
alert相关字段,否则系统还是会弹出通知弹窗 - 角标数字建议直接传具体数值(比如
3),如果需要增量更新,更可靠的方式是在客户端维护角标计数,再通过推送通知客户端更新
内容的提问来源于stack exchange,提问作者EgzonArifi




