iOS推送仅真机Debug模式可用,App Store版本无法接收推送求助
iOS生产环境无法接收FCM主题推送问题排查与解决
问题背景
项目基于Firebase云函数实现主题推送通知,Android端在Debug、真机及Play Store版本均正常,但iOS仅Debug模式能接收推送,App Store下载的生产版本完全收不到,启动时还会抛出APNS设备Token未设置的错误。
现有代码片段
用户订阅主题代码
await FirebaseMessaging.instance.subscribeToTopic('mytopic');
云函数推送代码
const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); const fcm = admin.messaging(); var payload = { "notification": { "title": msgData.name, "body": msgData.title, "click_action": 'FLUTTER_NOTIFICATION_CLICK', "android_channel_id": "my_channel_id", }, "data": { "content": msgData.content, "title": msgData.title, } }; return fcm.sendToTopic("/topics/" + 'mytopic', payload);
iOS启动错误日志
[FirebaseMessaging][I-FCM002022] APNS device token not set before retrieving FCM Token for Sender ID '123456789'. Notifications to this FCM Token will not be delivered over APNS.Be sure to re-retrieve the FCM token once the APNS device token is set.
已尝试的iOS配置代码
AppDelegate.swift
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) application.registerForRemoteNotifications()//尝试解决生产模式推送问题 return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }
Flutter端权限请求代码
NotificationSettings settings = await FirebaseMessaging.instance.requestPermission( alert: true, badge: true, provisional: false, sound: true, ); if (settings.authorizationStatus == AuthorizationStatus.authorized) { print('User granted permission'); String? token = await FirebaseMessaging.instance.getToken(); print("The token is " + token!); // 处理收到的通知 } else { print('User declined or has not accepted permission'); } /// 更新iOS前台通知展示选项,允许悬浮通知 await FirebaseMessaging.instance .setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true, );
排查与解决步骤
确认APNS生产证书配置
- 登录Apple开发者后台,检查
Certificates, Identifiers & Profiles中,对应App的APNS生产证书(Production SSL Certificate)是否有效、未过期,且已正确关联到App ID。 - 打开Firebase控制台项目的
Cloud Messaging模块,确认已上传最新的APNS生产证书(p12格式),且证书密码正确。
- 登录Apple开发者后台,检查
修正FCM Token获取时机
错误核心是APNS Token未生成就获取了FCM Token,需在APNS Token成功获取后再刷新FCM Token:
在AppDelegate.swift中添加APNS Token回调,并重新获取FCM Token:import FirebaseMessaging // 需新增导入 @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { // ...原有didFinishLaunchingWithOptions代码... override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { Messaging.messaging().apnsToken = deviceToken // 重新获取FCM Token Messaging.messaging().token { token, error in if let error = error { print("获取FCM Token失败: \(error)") } else if let token = token { print("新FCM Token: \(token)") // 可在此处将Token上传服务器或重新订阅主题 } } super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) } }检查Xcode打包配置
- 打包时确保
Signing & Capabilities中Push Notifications能力已开启,且Provisioning Profile为生产环境(App Store/Ad Hoc)配置,包含推送权限。 - 确认
Build Settings中Code Signing Identity在Release模式下选择的是生产证书。
- 打包时确保
验证主题订阅状态
生产环境中Token可能会更新,需在Token变化时重新订阅主题:
修改Flutter端代码:if (settings.authorizationStatus == AuthorizationStatus.authorized) { print('用户已授权通知'); // 监听Token变化,自动重新订阅 FirebaseMessaging.instance.onTokenRefresh.listen((newToken) { print("Token更新: $newToken"); FirebaseMessaging.instance.subscribeToTopic('mytopic'); }); // 初始获取Token并订阅 String? token = await FirebaseMessaging.instance.getToken(); if (token != null) { print("当前Token: $token"); await FirebaseMessaging.instance.subscribeToTopic('mytopic'); } }修正云函数推送目标格式
sendToTopic无需手动拼接/topics/,Firebase会自动处理,修正代码:return fcm.sendToTopic('mytopic', payload);
内容的提问来源于stack exchange,提问作者Garth
相关产品推荐
相关产品推荐

