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

独立Watch OS应用前台处理Firebase Cloud Message通知方案咨询

独立Apple Watch应用集成FCM通知接收问题

我正尝试在独立Apple Watch应用中监听Firebase Cloud Message通知。在Flutter框架中,可通过以下代码实现:

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    //按需处理消息
});

我已查阅官方文档发送静默通知,但通过Firebase控制台和Postman测试时,均无法收到通知。

当前使用的Swift代码

import SwiftUI
import Firebase

@main
struct Curiousfly_Watch_Watch_AppApp: App {
  @WKApplicationDelegateAdaptor(FCMWatchAppDelegate.self) var appDelegate
  var body: some Scene {
    WindowGroup {
      AuthenticationView()
    }
  }
}

// MARK: - WKApplicationDelegate
class FCMWatchAppDelegate: NSObject, WKApplicationDelegate, MessagingDelegate {
  @AppStorage("fcmToken") var fToken = ""
  func applicationDidFinishLaunching() {
    FirebaseApp.configure()
    let notificationCenter = UNUserNotificationCenter.current()
    notificationCenter.requestAuthorization(options: [.alert, .sound]) { granted, error in
      if granted {
        WKApplication.shared().registerForRemoteNotifications()
      }
    }
    Messaging.messaging().delegate = self
  }

  func didRegisterForRemoteNotifications(withDeviceToken deviceToken: Data) {
    print("APNS didRegisterForRemoteNotifications. Got device token \(deviceToken)")
    Messaging.messaging().apnsToken = deviceToken
  }
    
  func application(_ application: Messaging,
   didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
   -> WKBackgroundFetchResult {
    if let messageID = userInfo["gcm.message_id"] {
      print("Message ID: \(messageID)")
    }
    print(userInfo)
    return WKBackgroundFetchResult.newData
  }
}

// MARK: - FCM MessagingDelegate
extension FCMWatchAppDelegate {
  func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
    // 使用此FCM令牌通过API或Firebase控制台测试推送
    print("FCM - didReceiveRegistrationToken \(String(describing: fcmToken))")
    fToken = fcmToken!
  }
}

终端输出

2022-12-28 17:38:25.857753+0530 Curiousfly Watch Watch App[384:120474] [SceneConfiguration] Info.plist contained no UIScene configuration dictionary (looking for configuration named "(no name)")
2022-12-28 17:38:25.858911+0530 Curiousfly Watch Watch App[384:120474] [SceneConfiguration] Info.plist contained no UIScene configuration dictionary (looking for configuration named "(no name)")
2022-12-28 17:38:25.859063+0530 Curiousfly Watch Watch App[384:120474] [SceneConfiguration] Info.plist contained no UIScene configuration dictionary (looking for configuration named "Default Configuration")

FCM - didReceiveRegistrationToken Optional("dYJGIGsXqEN0p7syDPCxU1:APA91bEFMfqb5C5o9yKgNwq7wOoX22olo1oRm9duPBEC6exfZwadb_7AF5GFaJ6aYV4KWebHhdTXwxDYKzxa7SC-DLUQoNkx15U5gS2POjf6oN_f0gVyabQwbfk3WPy_je3yejeZxjZh")
2022-12-28 17:38:26.036943+0530 Curiousfly Watch Watch App[384:120474] void * _Nullable NSMapGet(NSMapTable * _Nonnull, const void * _Nullable): map table argument is NULL
2022-12-28 17:38:26.067010+0530 Curiousfly Watch Watch App[384:120688] 10.3.0 - [FirebaseMessaging][I-FCM002022] APNS device token not set before retrieving FCM Token for Sender ID '984386421852'. 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.
Dec 28 17:38:26  Curiousfly Watch Watch App[384] <Warning>: 10.3.0 - [FirebaseMessaging][I-FCM002022] APNS device token not set before retrieving FCM Token for Sender ID '984386421852'. 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.
2022-12-28 17:40:18.138006+0530 Curiousfly Watch Watch App[384:121080] Task <136B1980-5B70-4907-B184-B55CF2D1F9D7>.<1> finished with error [-1001] Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSLocalizedDescription=The request timed out., _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <136B1980-5B70-4907-B184-B55CF2D1F9D7>.<1>, _kCFStreamErrorCodeKey=-2103, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <136B1980-5B70-4907-B184-B55CF2D1F9D7>.<1>"
), NSErrorFailingURLStringKey=https://device-provisioning.googleapis.com/checkin, _kCFStreamErrorDomainKey=4, NSErrorFailingURLKey=https://device-provisioning.googleapis.com/checkin}
2022-12-28 17:41:50.385390+0530 Curiousfly Watch Watch App[384:120474] [bg_app_refresh] -[SPApplicationDelegate prepareForSnapshotWithReason:userInfo:completion:]:3099: PrepareForSnapshot called on an application that is running in the dock or foreground, completing immediately
2022-12-28 17:41:55.624735+0530 Curiousfly Watch Watch App[384:120683] [AXRuntimeCommon] Unknown client: Curiousfly Watch Watch App

2022-12-28 17:42:24.963294+0530 Curiousfly Watch Watch App[384:121587] [AXRuntimeCommon] AX Lookup problem - errorCode:1100 error:Permission denied portName:'com.apple.iphone.axserver' PID:227 (
    0   AXRuntime                           0x3aabc450 _AXGetPortFromCache + 1016
    1   AXRuntime                           0x3aabeac4 AXUIElementPerformFencedActionWithValue + 940
    2   UIKit                               0x03d3dc64 __64-[_UIRemoteViewAccessibility _accessibilityUnregisterRemoteView]_block_invoke_2 + 60
    3   libdispatch.dylib                   0x0357b848 _dispatch_call_block_and_release + 24
    4   libdispatch.dylib                   0x0357d040 _dispatch_client_callout + 16
    5   libdispatch.dylib                   0x03584168 _dispatch_lane_serial_drain + 660
    6   libdispatch.dylib                   0x03584dfc _dispatch_lane_invoke + 436
    7   libdispatch.dylib                   0x0359077c _dispatch_workloop_worker_thread + 712
    8   libsystem_pthread.dylib             0x7fb9d47c _pthread_wqthread + 280
    9   libsystem_pthread.dylib             0x7fb9d51c start_wqthread + 8
)
2022-12-28 17:42:24.965915+0530 Curiousfly Watch Watch App[384:121587] [AXRuntimeCommon] AX Lookup problem - errorCode:1100 error:Permission denied portName:'com.apple.iphone.axserver' PID:227 (
    0   AXRuntime                           0x3aabc450 _AXGetPortFromCache + 1016
    1   AXRuntime                           0x3aabeac4 AXUIElementPerformFencedActionWithValue + 940
    2   UIKit                               0x03d3dc64 __64-[_UIRemoteViewAccessibility _accessibilityUnregisterRemoteView]_block_invoke_2 + 60
    3   libdispatch.dylib                   0x0357b848 _dispatch_call_block_and_release + 24
    4   libdispatch.dylib                   0x0357d040 _dispatch_client_callout + 16
    5   libdispatch.dylib                   0x03584168 _dispatch_lane_serial_drain + 660
    6   libdispatch.dylib                   0x03584dfc _dispatch_lane_invoke + 436
    7   libdispatch.dylib                   0x0359077c _dispatch_workloop_worker_thread + 712
    8   libsystem_pthread.dylib             0x7fb9d47c _pthread_wqthread + 280
    9   libsystem_pthread.dylib             0x7fb9d51c start_wqthread + 8
)

2022-12-28 17:42:38.041972+0530 Curiousfly Watch Watch App[384:121552] PDTask <ED5955B6-BACE-457C-8B32-43C101C4EDA5>.<2> finished with error [9] Error Domain=NSPOSIXErrorDomain Code=9 "Bad file descriptor" UserInfo={_kCFStreamErrorCodeKey=9, _kCFStreamErrorDomainKey=1, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataPDTask <ED5955B6-BACE-457C-8B32-43C101C4EDA5>.<2>",
    "LocalDataTask <ED5955B6-BACE-457C-8B32-43C101C4EDA5>.<2>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataPDTask <ED5955B6-BACE-457C-8B32-43C101C4EDA5>.<2>}
2022-12-28 17:42:38.042704+0530 Curiousfly Watch Watch App[384:121552] Task <ED5955B6-BACE-457C-8B32-43C101C4EDA5>.<3> finished with error [9] Error Domain=NSPOSIXErrorDomain Code=9 "Bad file descriptor" UserInfo={_kCFStreamErrorCodeKey=9, _kCFStreamErrorDomainKey=1, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <ED5955B6-BACE-457C-8B32-43C101C4EDA5>.<3>",
    "LocalDataPDTask <ED5955B6-BACE-457C-8B32-43C101C4EDA5>.<2>",
    "LocalDataTask <ED5955B6-BACE-457C-8B32-43C101C4EDA5>.<2>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <ED5955B6-BACE-457C-8B32-43C101C4EDA5>.<3>}

问题分析与解决步骤

从终端警告APNS device token not set before retrieving FCM Token可知,核心问题是FCM令牌在APNS设备令牌配置前生成,导致该令牌无法通过APNS接收通知。

  1. 重新获取有效FCM令牌
    在设置apnsToken后,主动调用令牌获取方法更新存储的FCM令牌:

    func didRegisterForRemoteNotifications(withDeviceToken deviceToken: Data) {
        print("APNS didRegisterForRemoteNotifications. Got device token \(deviceToken)")
        Messaging.messaging().apnsToken = deviceToken
        // 重新获取并更新FCM令牌
        Messaging.messaging().token { token, error in
            if let error = error {
                print("FCM令牌获取失败: \(error)")
            } else if let token = token {
                print("更新后的FCM令牌: \(token)")
                fToken = token
            }
        }
    }
    
  2. 修正通知接收方法签名
    WatchOS的远程通知接收方法属于WKApplicationDelegate,而非Messaging,修正方法签名:

    func application(_ application: WKApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) async -> WKBackgroundFetchResult {
        if let messageID = userInfo["gcm.message_id"] {
            print("消息ID: \(messageID)")
        }
        print(userInfo)
        return .newData
    }
    
  3. 补充Info.plist的Scene配置
    针对终端的Scene配置警告,在Watch App的Info.plist中添加以下配置:

    <key>UIApplicationSceneManifest</key>
    <dict>
        <key>UIApplicationSupportsMultipleScenes</key>
        <false/>
        <key>UISceneConfigurations</key>
        <dict>
            <key>UIWindowSceneSessionRoleApplication</key>
            <array>
                <dict>
                    <key>UISceneConfigurationName</key>
                    <string>Default Configuration</string>
                    <key>UISceneDelegateClassName</key>
                    <string></string>
                </dict>
            </array>
        </dict>
    </dict>
    
  4. 确保推送Payload符合WatchOS要求
    发送静默通知时,Payload需包含content-available: 1,同时设置正确的APNS头部:

    {
      "to": "你的FCM令牌",
      "content_available": true,
      "apns": {
        "headers": {
          "apns-push-type": "background",
          "apns-topic": "你的Watch App Bundle ID"
        },
        "payload": {
          "data": {
            "key": "value"
          }
        }
      }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:45:33