推送通知在Firebase 4.0中无效

我今天更新了我的pod到新的Firebase 4.0。 我完成了建议的更改并从Github示例中获取了代码。 我会说实话我不知所措,我拿着FCM令牌并从firebase控制台发送消息,我什么也得不到。

我刷新,它说消息已发送,但我检查控制台和设备,没有任何东西。 我错过了什么?

这是我的appdelegate:

// // Created by Erik Grosskurth on 4/24/17. // import UIKit import FirebaseAnalytics import FirebaseInstanceID import FirebaseMessaging import UserNotifications import SystemConfiguration import MobileCoreServices import Quickblox import QuickbloxWebRTC let kQBApplicationID:UInt = 3545252534 let kQBAuthKey = "udfgsegsetrgsextr" let kQBAuthSecret = "setbsetbsetbsetrbset" let kQBAccountKey = "sbrtsbrtbsrtbsrtbrt" @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? let gcmMessageIDKey = "gcm.message_id" func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // [START register_for_notifications] FirebaseApp.configure() Messaging.messaging().delegate = self if #available(iOS 10.0, *) { // For iOS 10 display notification (sent via APNS) 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() if (Messaging.messaging().fcmToken != nil) { DataModel.sharedInstance.sessionInfo.FirebaseAccessToken = Messaging.messaging().fcmToken! print("FCM token: \(DataModel.sharedInstance.sessionInfo.FirebaseAccessToken)") }else { print("token was nil") } // [END register_for_notifications] //Quickblox config QBSettings.setApplicationID(kQBApplicationID) QBSettings.setAuthKey(kQBAuthKey) QBSettings.setAuthSecret(kQBAuthSecret) QBSettings.setAccountKey(kQBAccountKey) // Set settings for zone QBSettings.setApiEndpoint("https://api.quickblox.com", chatEndpoint: "chat.quickblox.com", forServiceZone: .production) // Activate zone QBSettings.setServiceZone(.production) QBSettings.setKeepAliveInterval(30) QBSettings.setAutoReconnectEnabled(true) QBRTCConfig.setStatsReportTimeInterval(1) QBRTCConfig.setDialingTimeInterval(5) QBRTCConfig.setAnswerTimeInterval(60) return true } // [START receive_message] func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) { Messaging.messaging().appDidReceiveMessage(userInfo) if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") } print(userInfo) } func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { Messaging.messaging().appDidReceiveMessage(userInfo) if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") } print(userInfo) completionHandler(UIBackgroundFetchResult.newData) } // when APNs has assigned the device a unique token func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { print("didRegisterForRemoteNotificationsWithDeviceToken()") Messaging.messaging().apnsToken = deviceToken //Messaging.messaging().setAPNSToken(deviceToken, type: MessagingAPNSTokenType.sandbox) //Messaging.messaging().setAPNSToken(deviceToken, type: MessagingAPNSTokenType.prod) //Messaging.messaging().setAPNSToken(deviceToken, type: MessagingAPNSTokenType.unknown) let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) DataModel.sharedInstance.sessionInfo.APNSAccessToken = deviceTokenString print("APNS Access Token: \(deviceTokenString)") } // [END receive_message] func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Unable to register for remote notifications: \(error.localizedDescription)") } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { QBChat.instance().disconnect { (error) in if error != nil { print("error: \(String(describing: error))") } else { print("success for applicationDidEnterBackground") } } } func applicationWillEnterForeground(_ application: UIApplication) { let qbUser = QBUUser() qbUser.id = DataModel.sharedInstance.qbLoginParams.id qbUser.password = DataModel.sharedInstance.sessionInfo.QBPassword QBChat.instance().connect(with: qbUser) { (error) in if error != nil { print("error: \(String(describing: error))") } else { print("success for applicationWillEnterForeground") } } } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(_ application: UIApplication) { QBChat.instance().disconnect { (error) in if error != nil { print("error: \(String(describing: error))") } else { print("success for applicationWillTerminate") } } } // LOCK IN PORTRAIT MODE func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return UIInterfaceOrientationMask(rawValue: UIInterfaceOrientationMask.portrait.rawValue) } } // [START ios_10_message_handling] @available(iOS 10, *) extension AppDelegate : UNUserNotificationCenterDelegate { // Receive displayed notifications for iOS 10 devices. func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let userInfo = notification.request.content.userInfo // With swizzling disabled you must let Messaging know about the message, for Analytics Messaging.messaging().appDidReceiveMessage(userInfo) // Print message ID. if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") } // Print full message. print(userInfo) // Change this to your preferred presentation option completionHandler([]) } func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo // Print message ID. if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") } // Print full message. print(userInfo) completionHandler() } } // [END ios_10_message_handling] extension AppDelegate : MessagingDelegate { // [START refresh_token] func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) { DataModel.sharedInstance.sessionInfo.FirebaseAccessToken = fcmToken print("Firebase registration token: \(fcmToken)") } // [END refresh_token] // [START ios_10_data_message] // Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground. // To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true. func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) { print("Received data message: \(remoteMessage.appData)") } // [END ios_10_data_message] } 

这是日志:

 2017-05-31 16:49:56.937067-0400 Telemed[1843:937699] [Firebase/Analytics][I-ACS003016] Firebase Analytics App Delegate Proxy is disabled. To log deep link campaigns manually, call the methods in FIRAnalytics+AppDelegate.h. 2017-05-31 16:49:56.937 Telemed[1843]  [Firebase/Analytics][I-ACS003016] Firebase Analytics App Delegate Proxy is disabled. To log deep link campaigns manually, call the methods in FIRAnalytics+AppDelegate.h. 2017-05-31 16:49:57.023568-0400 Telemed[1843:937706] [Firebase/Analytics][I-ACS005000] The AdSupport Framework is not currently linked. Some features will not function properly. Learn more at 2017-05-31 16:49:57.023 Telemed[1843]  [Firebase/Analytics][I-ACS005000] The AdSupport Framework is not currently linked. Some features will not function properly. Learn more at 2017-05-31 16:49:57.028454-0400 Telemed[1843:937697] [Firebase/Analytics][I-ACS023007] Firebase Analytics v.4000000 started 2017-05-31 16:49:57.028 Telemed[1843]  [Firebase/Analytics][I-ACS023007] Firebase Analytics v.4000000 started 2017-05-31 16:49:57.029042-0400 Telemed[1843:937697] [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see ) 2017-05-31 16:49:57.029 Telemed[1843]  [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see ) FCM token: myTokenIsHere 2017-05-31 16:49:57.101756-0400 Telemed[1843:937699] [Firebase/Analytics][I-ACS032003] iAd framework is not linked. Search Ad Attribution Reporter is disabled. 2017-05-31 16:49:57.102 Telemed[1843]  [Firebase/Analytics][I-ACS032003] iAd framework is not linked. Search Ad Attribution Reporter is disabled. 2017-05-31 16:49:57.103700-0400 Telemed[1843:937697] [Firebase/Analytics][I-ACS023012] Firebase Analytics enabled 2017-05-31 16:49:57.103 Telemed[1843]  [Firebase/Analytics][I-ACS023012] Firebase Analytics enabled Destroyed Session but Saved Login 2017-05-31 16:49:57.158678-0400 Telemed[1843:937637] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2017-05-31 16:49:57.159102-0400 Telemed[1843:937637] [MC] Reading from public effective user settings. didRegisterForRemoteNotificationsWithDeviceToken() APNS Access Token: 091F01B... 

>>> ——> **已解决 <——- <<< **

深入潜入故障排除和最终的终极事件……如下所示: https //github.com/firebase/quickstart-ios/issues/290

在拍摄问题时特别感谢他的时间!

Firebase Cloud Messaging在iOS上正确设置非常复杂,因为您必须确保您的APN配置正常工作,然后在其上添加FCM。

APN设置

APNs身份validation密钥也非常.p8苹果,因为它们不会过期,适用于沙箱和生产环境,并且相同的密钥(如.p8文件)可用于向该Apple开发人员帐户下的所有应用程序发送推送通知。

它还为潜在的失败引入了一个新领域: 拼写错误 。 您可以输入随机包ID,只要在Xcode中配置了正确的“团队”,您的应用就会很高兴获得APNs设备令牌。

通过APN向该设备令牌发送通知(我使用此脚本通过HTTP / 2 + Auth Keys发送测试通知)将产生DeviceTokenNotForTopic错误,这样可以帮助您找出问题所在。

清单

  • 确保您的应用包ID与您要发送的包ID相匹配
  • 确保您拥有权利文件,至少将aps-environment密钥设置为development (在Xcode中,这将在发布版本中自动更新)
  • 如果在Firebase等其他SDK中使用“自动”配置(即调配),请确保在application:didRegisterForRemoteNotificationsWithDeviceToken:获取APNs令牌application:didRegisterForRemoteNotificationsWithDeviceToken: . 这至少证实你的APN设置没问题(但你可能还有错字)

FCM设置

请确保您使用的GoogleService-Info.plist文件与plist中的BUNDLE_ID键位于同一个应用程序中。 我见过开发人员认为,因为APNs Keys应该可以在所有应用程序中正常工作,所以相同的GoogleService-Info.plist在各种应用程序GoogleService-Info.plist都可以正常使用,但事实并非如此。

测试

我还建议使用终端的FCM HTTP API发送测试通知,以帮助调试问题。 与Firebase Notifications Console不同,它会为您提供遇到的任何原始错误。 这是一个例子:

 curl -X "POST" "https://fcm.googleapis.com/fcm/send" \ -H "Authorization: key=SERVER_KEY" \ -H "Content-Type: application/json" \ -d $'{ "notification": { "body": "Testing with direct FCM API", "title": "Test Message", "badge": "0", "sound": "default" }, "registration_ids": [ "FCM_TOKEN" ] }' 

使用Firebase控制台>项目设置>云消息传递>服务器密钥中的值填写您的SERVER_KEY 。 用您的FCM令牌替换FCM_TOKEN

当我使用FCM SDK时,我使用Paw向我的应用程序发送测试通知。