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

独立Apple tvOS应用无法通过FCM展示通知的技术问题

tvOS应用集成Firebase Messaging后无法展示通知的排查方案

问题背景

开发独立tvOS应用,已完成FCM与APNS配置,但集成Firebase Messaging后无法展示通知,相关代码、控制台输出及环境信息如下:

集成代码

import SwiftUI
import Firebase

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
    @AppStorage("fcmToken") var fToken = ""
    let gcmMessageIDKey = "gcm.message_id"
    
    func userNotificationCenter(_ center: UNUserNotificationCenter,
            willPresent notification: UNNotification,
            withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.banner, .badge, .sound])
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()

        // Register for remote notifications
        let notificationCenter = UNUserNotificationCenter.current()
        notificationCenter.delegate = self
        notificationCenter.requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
            if granted {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }

        Messaging.messaging().delegate = self

        return true
    }

    // MARK: - Push Notifications

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
        let deviceTokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
        print("APNS device token: \(deviceTokenString)")
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications with error: \(error.localizedDescription)")
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        if userInfo[gcmMessageIDKey] != nil {
            print("Received data message: \(userInfo)")
            completionHandler(.newData)
        }
    }

    // MARK: - Messaging

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        guard let fcmToken = fcmToken else { return }
        fToken = fcmToken
        print("FCM token: \(fcmToken)")
    }
}

@main
struct SomeExampleApp_TVApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

控制台输出

2023-04-24 20:04:46.212321+0530 SomeExampleApp[1262:39696] void * _Nullable NSMapGet(NSMapTable * _Nonnull, const void * _Nullable): map table argument is NULL
2023-04-24 20:04:46.221547+0530 SomeExampleApp[1262:39865] 9.6.0 - [FirebaseMessaging][I-FCM002022] APNS device token not set before retrieving FCM Token for Sender ID '012849237482'. 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.
FCM token: someFcmToken
2023-04-24 20:04:48.650580+0530 SomeExampleApp[1262:39858] [] nw_path_necp_check_for_updates Failed to copy updated result (22)
FCM token: someFcmToken
APNS device token: someApnToken
Received data message: [AnyHashable("aps"): {
    alert =     {
        body = "Entry Lights turned on as you entered Office";
        title = "Location Automation";
    };
    "content-available" = 1;
}, AnyHashable("google.c.a.e"): 1, AnyHashable("google.c.sender.id"): 984386421852, AnyHashable("google.c.fid"): citAzVs8zUeFtNaj_EZJmN, AnyHashable("gcm.message_id"): 1682346907169586]
Received data message: [AnyHashable("google.c.a.e"): 1, AnyHashable("gcm.message_id"): 1682347026515009, AnyHashable("aps"): {
    alert =     {
        body = "Entry Lights turned on as you entered Office";
        title = "Location Automation";
    };
    "content-available" = 1;
}, AnyHashable("google.c.fid"): citAzVs8zUeFtNaj_EZJmN, AnyHashable("google.c.sender.id"): 012849237482]
Received data message: [AnyHashable("aps"): {
    alert =     {
        body = "Entry Lights turned on as you entered Office";
        title = "Location Automation";
    };
    "content-available" = 1;
}, AnyHashable("google.c.sender.id"): 984386421852, AnyHashable("gcm.message_id"): 1682347042989389, AnyHashable("google.c.a.e"): 1, AnyHashable("google.c.fid"): citAzVs8zUeFtNaj_EZJmN]

环境信息

  • Firebase SDK版本:9.6.0
  • Xcode版本:14.2 (14C18)
  • 安装方式:Swift Package Manager
  • 使用的Firebase产品:Messaging
  • 目标平台:tvOS

排查与解决方案

  1. 修复FCM Token与APNS Token同步问题
    控制台提示APNS device token not set before retrieving FCM Token,说明FCM Token先于APNS Token获取,导致该Token无法通过APNS推送通知。在didRegisterForRemoteNotificationsWithDeviceToken方法中添加主动刷新FCM Token的逻辑:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    Messaging.messaging().apnsToken = deviceToken
    let deviceTokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    print("APNS device token: \(deviceTokenString)")
    
    // 主动刷新FCM Token
    Messaging.messaging().token { token, error in
        if let error = error {
            print("Error fetching FCM registration token: \(error)")
        } else if let token = token {
            print("Refreshed FCM token: \(token)")
            self.fToken = token
        }
    }
}
  1. 补充后台通知处理代理方法
    当前仅实现了前台展示通知的willPresent方法,缺少后台/未启动状态下的通知处理方法,添加以下代码:
func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {
    // 可添加通知点击后的业务逻辑
    completionHandler()
}
  1. 调整通知负载格式
    tvOS对通知负载有特定要求:
  • 确保aps字典中alert的title和body字段非空
  • 若仅需展示通知而非静默更新,移除content-available=1字段;保留则需确保应用开启后台刷新权限
  • 确认FCM发送的是通知消息而非数据消息,数据消息不会自动触发系统通知弹窗
  1. 验证配置一致性
  • 检查Firebase控制台的APNS证书环境(开发/生产)与Xcode打包配置匹配
  • 确认Xcode项目的Bundle Identifier与Firebase应用的Bundle ID完全一致
  • 核实控制台中出现的两个Sender ID均已正确配置关联
  1. 升级Firebase SDK版本
    当前9.6.0版本存在部分tvOS适配问题,建议升级至最新稳定版,修复已知的推送同步bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:59:57