Firebase iOS端如何从推送通知中获取数据并保存到变量
嗨,我来帮你搞定这个问题!你已经成功把推送发到iOS设备了,现在要把那些自定义字段存到变量里对吧?其实分几种场景处理就行,我给你一步步讲清楚:
1. 先确认你的推送Payload结构
首先得明确你的推送数据是放在Payload的哪个节点里——Firebase推送分两种类型:
- 通知消息:带
notification节点(包含alert、body等显示内容),自定义字段一般放在data节点下 - 数据消息:只有
data节点,属于静默推送或自定义处理的推送
举个你场景的典型Payload示例:
{
"to": "/topics/your_topic",
"notification": {
"body": "这是你的message_body"
},
"data": {
"topic_name": "your_test_topic",
"data_message": "需要保存的自定义数据",
"sound": "default"
}
}
不同节点下的字段提取路径不一样,这点要注意~
2. 前台运行时提取数据
当APP在前台活跃状态时,你可以通过Firebase Messaging的代理或者UserNotifications的代理来捕获推送并提取数据:
方法一:用Firebase Messaging代理
import FirebaseMessaging import UserNotifications class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 初始化Firebase FirebaseApp.configure() Messaging.messaging().delegate = self // 请求通知权限并注册远程推送 UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in guard granted else { return } DispatchQueue.main.async { application.registerForRemoteNotifications() } } return true } // 前台接收推送时触发这个方法 func messaging(_ messaging: Messaging, didReceiveRemoteNotification remoteMessage: [AnyHashable : Any]) { // 提取数据到变量(根据你的Payload结构调整路径) let topicName = remoteMessage["data"]?["topic_name"] as? String ?? "" let messageBody = remoteMessage["notification"]?["body"] as? String ?? "" let dataMessage = remoteMessage["data"]?["data_message"] as? String ?? "" let sound = remoteMessage["data"]?["sound"] as? String ?? "" // 这里就可以把变量存起来啦,比如存到UserDefaults UserDefaults.standard.set(topicName, forKey: "savedTopic") UserDefaults.standard.set(dataMessage, forKey: "savedDataMessage") UserDefaults.standard.synchronize() // 也可以直接用这些变量做业务逻辑,比如更新UI print("前台收到推送:\(messageBody),主题:\(topicName)") } }
方法二:用UserNotifications代理(更灵活)
如果你想统一管理前台和后台的推送处理,推荐用这个:
extension AppDelegate: UNUserNotificationCenterDelegate { // 前台收到通知时触发,可以控制是否显示通知 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let userInfo = notification.request.content.userInfo // 提取数据 let topicName = userInfo["data"]?["topic_name"] as? String ?? "" let messageBody = userInfo["notification"]?["body"] as? String ?? "" // 保存变量 let savedMessage = messageBody print("前台提取到消息:\(savedMessage)") // 允许前台显示通知(默认前台不显示,按需设置) completionHandler([.alert, .sound]) } }
3. 后台/点击通知时提取数据
当APP在后台或者被杀死状态,用户点击通知打开APP时,要通过UNUserNotificationCenterDelegate的另一个方法处理:
extension AppDelegate: UNUserNotificationCenterDelegate { // 用户点击通知时触发(后台/杀死状态打开APP) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo // 提取数据到变量 let topicName = userInfo["data"]?["topic_name"] as? String ?? "" let dataMessage = userInfo["data"]?["data_message"] as? String ?? "" // 保存变量,比如存到本地数据库或者ViewModel print("从通知点击提取到主题:\(topicName)") // 一定要调用completionHandler completionHandler() } }
4. 几个关键注意事项
- 确保在Xcode的
Capabilities里开启了Background Modes,并勾选Remote notifications(后台推送需要) - 如果是静默推送,Payload里必须包含
"content-available": 1字段,且不能有notification节点 - 提取字段时要做可选值绑定(用
?? ""设置默认值),避免因为字段缺失导致崩溃 - 如果你用SwiftUI,也可以把提取逻辑放到
App结构体或者专门的通知管理类里,原理和UIKit一致
内容的提问来源于stack exchange,提问作者Dante
相关产品推荐
相关产品推荐

