独立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接收通知。
重新获取有效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 } } }修正通知接收方法签名
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 }补充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>确保推送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
相关产品推荐
相关产品推荐

