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

在Flutter中使用firebase_messaging插件时设置UNNotificationCenterDelegate的冲突问题

在Flutter中使用firebase_messaging插件时设置UNNotificationCenterDelegate的冲突问题

哥们我太懂你这个坑了!我之前做Flutter推送的时候也踩过一模一样的雷——当你自己在AppDelegate里设置了UNUserNotificationCenter的代理,还实现了didReceiveNotificationResponse方法后,是不是发现Firebase Messaging原本的通知点击逻辑突然失效了?

问题根源其实很简单

firebase_messaging插件内部已经悄悄把UNUserNotificationCenter的代理设置成了它自己的处理对象(就是你提到的FLTFirebaseMessaging相关类),当你在didFinishLaunchingWithOptions里把代理改成self时,直接把插件的代理覆盖了,插件自然收不到通知响应的回调,原有功能就崩了。

最稳妥的解决方案:代理转发

我们不用把插件的代理完全挤走,而是做个“中间商”——先保存插件的原始代理,处理完自己的自定义按钮逻辑后,再把事件转发给原始代理,这样两边的逻辑都能正常跑。

具体步骤如下:

  1. 先在AppDelegate里声明一个变量,用来保存插件的原始代理:
@property (nonatomic, weak) id<UNUserNotificationCenterDelegate> originalFCMNotificationDelegate;
  1. 在didFinishLaunchingWithOptions里,先存下插件的代理,再把自己设为新代理:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 先保存Firebase已经设置好的原始代理
    self.originalFCMNotificationDelegate = [UNUserNotificationCenter currentNotificationCenter].delegate;
    // 再把当前AppDelegate设为代理
    [UNUserNotificationCenter currentNotificationCenter].delegate = self;
    
    // 其他初始化代码...
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
  1. 在你的didReceiveNotificationResponse方法里,先处理自定义按钮逻辑,再转发给原始代理:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center 
didReceiveNotificationResponse:(UNNotificationResponse *)response
     withCompletionHandler:(void (^)(void))completionHandler {
    
    // 第一步:处理你自己的自定义动作按钮逻辑
    if ([response.actionIdentifier isEqualToString:@"你的自定义按钮ID"]) {
        // 通过MethodChannel给Flutter侧发送事件
        FlutterMethodChannel *notificationChannel = [FlutterMethodChannel methodChannelWithName:@"com.your.app/notification_actions" binaryMessenger:self.flutterViewController];
        [notificationChannel invokeMethod:@"handleCustomAction" arguments:@{
            @"actionId": response.actionIdentifier,
            @"notificationData": response.notification.request.content.userInfo
        }];
    }
    
    // 第二步:把事件转发给Firebase的原始代理,保证插件原有逻辑正常运行
    if (self.originalFCMNotificationDelegate && [self.originalFCMNotificationDelegate respondsToSelector:@selector(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)]) {
        [self.originalFCMNotificationDelegate userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
    } else {
        // 万一原始代理不存在,也必须调用completionHandler,否则会导致App卡死
        completionHandler();
    }
}
  1. 如果你还需要处理前台通知展示的逻辑,记得对willPresentNotification方法也做同样的转发:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    // 这里可以加自己的前台通知处理逻辑(比如自定义展示样式)
    
    // 转发给Firebase原始代理
    if (self.originalFCMNotificationDelegate && [self.originalFCMNotificationDelegate respondsToSelector:@selector(userNotificationCenter:willPresentNotification:withCompletionHandler:)]) {
        [self.originalFCMNotificationDelegate userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
    } else {
        // 默认展示选项:横幅+提示音
        completionHandler(UNNotificationPresentationOptionBanner | UNNotificationPresentationOptionSound);
    }
}

最后别忘了在Flutter侧注册MethodChannel的监听,这样iOS端发过来的自定义动作事件才能被Flutter接收处理哦~

备注:内容来源于stack exchange,提问作者Thijs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 12:04:34