推送通知在Firebase 4.0中无效

时间:2017-05-31 20:30:08

标签: ios firebase swift3 push-notification firebase-cloud-messaging

我今天将我的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] <Warning> [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] <Warning> [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] <Notice> [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] <Notice> [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] <Warning> [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] <Notice> [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...

&GT;&GT;&GT; ------&GT; **已解决&lt; -------&lt;&lt;&lt; **

深入潜水进入故障排除和最后的终极事件......跟随这条线: https://github.com/firebase/quickstart-ios/issues/290

特别感谢THE RIZ他的出现问题!

2 个答案:

答案 0 :(得分:15)

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

APNs设置

APNs身份验证密钥对Apple来说也很不错,因为它们不会过期,适用于沙箱和生产环境,并且相同的密钥(作为DeviceTokenNotForTopic文件)可用于发送推送通知到该Apple Developer帐户下的所有应用程序。

它还为潜在的失败引入了一个新领域:拼写错误。您可以输入随机捆绑ID,只要正确的&#34;团队&#34;在Xcode中配置,您的应用程序将很乐意获得APNs设备令牌。

通过APN向我的设备令牌发送通知(我使用this script通过HTTP / 2 +身份验证密钥发送测试通知)将产生aps-environment错误,这样可以帮助您弄清楚出了问题。

<强>清单

  • 确保您的应用套装ID与您要发送到
  • 的套件ID相匹配
  • 确保您拥有一个权利文件,至少development密钥设置为application:didRegisterForRemoteNotificationsWithDeviceToken:(这在Xcode的发布版本中会自动更新)
  • 如果使用&#34;自动&#34;在其他SDK(如Firebase)中进行配置(即调配),确保您在GoogleService-Info.plist中获得了APN令牌。这至少证实你的APN设置没问题(但你可能还有错字)

FCM设置

确保您使用的BUNDLE_ID文件与plist中的GoogleService-Info.plist键位于同一个应用中。我已经看到开发人员认为,因为APNs Keys应该可以在所有应用中正常运行,所以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" ] }' 在各种应用中都相同,但事实并非如此。

<强>测试

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

SERVER_KEY

使用Firebase控制台中的值&gt;填写FCM_TOKEN;项目设置&gt;云消息传递&gt;服务器密钥。将document.documentElement.style.setProperty(替换为您的FCM令牌。

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

答案 1 :(得分:0)

我正在使用.p8文件发送通知,尽管没有通知。然后我意识到.p8文件下的Apple Push Notifications服务(APN)未启用。

启用它后,现在一切似乎都可以使用了。 enter image description here

相关问题