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

iOS11.4.1下Firebase Messaging无法触发onBackgroundMessage回调

Flutter Firebase Messaging iOS端onBackgroundMessage回调不触发排查方案

问题表现

  • 应用正常接入Firebase后,前台状态onMessage回调可正常接收推送,后台(未终止)状态下onBackgroundMessage绑定的处理函数始终无响应,debug、release构建环境测试结果一致
  • 系统层面已成功接收到APNs推送,可通过Mac端Console日志确认消息投递,但Flutter层回调未触发
  • 排除flutter_local_notifications通知展示环节的干扰,问题出在消息回调注册/投递链路本身

已完成的前置配置校验

  • 已通过Firebase控制台关联应用,GoogleService-Info.plist已正确添加至iOS项目目录
  • 已在Firebase控制台上传有效的APNs认证密钥
  • 已定义顶层函数作为后台消息处理回调,且在main()中执行了注册:
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  // 后台/终止状态下始终未被调用
  print("Handling a background message: ${message.messageId}");
  // 自定义业务处理逻辑
}

// main函数中注册回调
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  • AppDelegate.swift已添加基础推送配置:
import UIKit
import Flutter
import Firebase
import FirebaseMessaging

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

   if #available(iOS 10.0, *) {
     UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
   }
  
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

}
  • 已开启Xcode项目的推送通知、后台模式(Remote notifications)能力
  • 应用已获取用户的通知权限授权
  • 通过Node.js Admin SDK发送仅含data字段、不含notification字段的静默推送,配置如下:
let message = {
    apns: {
        headers: {
            'apns-priority': '5',
        },
        payload: {
          aps: {
            contentAvailable: true
          },
        },
      },
    android: {
        priority: 'normal',
    },
    
    data: {
        title: "Test",
        message: "Test",
        url: "https://www.google.com/"
    },
    topic: topic
};
  • Console日志确认系统已收到推送:
default 20:48:06.069282+0300    SpringBoard Received incoming message on topic com.matkonit at priority 5
default 20:48:06.082948+0300    SpringBoard [com.matkonit] Received remote notification request 3823-43DB [ waking: 0, hasAlertContent: 0, hasSound: 0 hasBadge: 0 hasContentAvailable: 1 hasMutableContent: 0 pushType: Background]
default 20:48:06.083005+0300    SpringBoard [com.matkonit] Process delivery of push notification 3823-43DB

核心修复步骤

1. 补全AppDelegate缺失的关键配置

现有AppDelegate代码缺少Firebase初始化调用、Messaging代理设置、远程通知注册逻辑,且类声明未遵守MessagingDelegate协议,是导致回调链路断裂的最常见原因,修复后完整代码如下:

import UIKit
import Flutter
import Firebase
import FirebaseMessaging

// 添加MessagingDelegate协议遵守
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, MessagingDelegate {
    
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    // 必须在注册Flutter插件前初始化Firebase
    FirebaseApp.configure()
    // 设置Firebase Messaging代理
    Messaging.messaging().delegate = self

    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self
      let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
      UNUserNotificationCenter.current().requestAuthorization(
        options: authOptions,
        completionHandler: { _, _ in }
      )
    } else {
      let settings: UIUserNotificationSettings =
        UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
      application.registerUserNotificationSettings(settings)
    }
    // 注册远程通知
    application.registerForRemoteNotifications()

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

注意:FirebaseApp.configure()必须在GeneratedPluginRegistrant.register调用前执行,否则Flutter插件无法正确获取Firebase实例,后台回调注册会静默失效。

2. 修正Flutter侧初始化顺序

确认main()函数中初始化逻辑顺序正确,错误的顺序会导致回调注册失败:

void main() async {
  // 必须第一行保证Flutter插件绑定初始化
  WidgetsFlutterBinding.ensureInitialized();
  // 必须先初始化Firebase App
  await Firebase.initializeApp();
  // 最后注册后台消息回调
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  runApp(const MyApp());
}

3. 修正静默推送的发送配置

现有推送配置存在多个不符合iOS APNs规则的问题,会导致系统不唤醒应用执行后台逻辑,修复后配置如下:

let message = {
    apns: {
        headers: {
            'apns-priority': '10', // 设为5会被系统节流延迟投递,静默推送需要立即唤醒应用必须设为10
            'apns-push-type': 'background', // iOS13+必填字段,明确指定为后台推送类型
        },
        payload: {
          aps: {
            contentAvailable: true
            // 静默推送的aps中不能包含alert/sound/badge字段,否则会被系统当作普通前台通知处理
          },
        },
      },
    android: {
        priority: 'high',
    },
    // data字段所有值必须为字符串类型,禁止传入数字、对象等非字符串值
    data: {
        title: "Test",
        message: "Test",
        url: "https://www.google.com/"
    },
    topic: topic
};

4. 排查系统级拦截问题

  • 测试时不要手动上滑杀死应用:iOS系统会默认拦截所有发给用户手动终止应用的静默推送,直到用户下次手动点开应用才会恢复投递
  • 确认应用的「后台App刷新」权限处于开启状态,路径:系统设置->对应应用->后台App刷新,开关关闭时系统不会唤醒应用执行后台回调
  • 测试时关闭低电量模式,低电量模式下系统会节流所有后台推送活动
  • 不要在Xcode附加调试器状态下测试后台回调:Xcode调试会干扰应用后台生命周期,正确测试方式为:Xcode运行安装应用后点击停止,手动从桌面打开应用,切到后台再发送推送
  • 首次安装应用后必须至少手动打开一次,系统才会为应用开通推送投递通道,未打开过的新装应用无法接收后台推送

5. 清理编译缓存

执行以下命令清理缓存,避免旧编译产物导致插件注册失效:

  1. 执行flutter clean清理Flutter构建缓存
  2. 删除iOS目录下的Pods文件夹、Podfile.lock文件
  3. 进入iOS目录执行pod install重新安装依赖
  4. 重新编译运行项目
    注意:尽量使用14.0.0以上稳定版firebase_messaging插件,避免beta/dev版本的已知兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:01:04