You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,
);

排查与解决步骤

  1. 确认APNS生产证书配置

    • 登录Apple开发者后台,检查Certificates, Identifiers & Profiles中,对应App的APNS生产证书(Production SSL Certificate)是否有效、未过期,且已正确关联到App ID。
    • 打开Firebase控制台项目的Cloud Messaging模块,确认已上传最新的APNS生产证书(p12格式),且证书密码正确。
  2. 修正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)
      }
    }
    
  3. 检查Xcode打包配置

    • 打包时确保Signing & Capabilities中Push Notifications能力已开启,且Provisioning Profile为生产环境(App Store/Ad Hoc)配置,包含推送权限。
    • 确认Build Settings中Code Signing Identity在Release模式下选择的是生产证书。
  4. 验证主题订阅状态
    生产环境中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');
      }
    }
    
  5. 修正云函数推送目标格式
    sendToTopic无需手动拼接/topics/,Firebase会自动处理,修正代码:

    return fcm.sendToTopic('mytopic', payload);
    

内容的提问来源于stack exchange,提问作者Garth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:10:16