推送通知在 Firebase 4.0 中不起作用 [英] Push Notifications not working in Firebase 4.0

查看:24
本文介绍了推送通知在 Firebase 4.0 中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天将 Pod 更新为新的 Firebase 4.0.我浏览了建议的更改并从 Github 示例中获取了代码.老实说,我不知所措,我拿走了 FCM 令牌并从 firebase 控制台发送了一条消息,但我什么也没得到.

I updated my pods today to the new Firebase 4.0. I went through the suggested changes and grabbed code from the Github example. I will be honest I am at a loss, I take the FCM Token and send a message from the firebase console and I get nothing.

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

I refresh and it says the message was sent but I check the console and the device and nothing is there. What am I missing?

这是我的应用代表:

//
//  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...

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

>>>------> **SOLVED <-------<<<**

要深入了解故障排除和最终的面部护理...请关注此主题:https://github.com/firebase/quickstart-ios/issues/290

特别感谢 RIZ 帮助他解决问题!!

SPECIAL THANKS TO THE RIZ FOR HIS TIME IN FIGURING OUT THE ISSUE!!

推荐答案

在 iOS 上正确设置 Firebase Cloud Messaging 非常复杂,因为您必须确保您的 APNs 配置有效,然后在其之上添加 FCM

Firebase Cloud Messaging is quite complex to get set up correctly on iOS, because you have to ensure that your APNs configuration is working, and then add FCM on top of that.

Apple 的 APNs Authentication Keys 也很不错,因为它们不会过期,在沙盒和生产环境中都可以使用,并且可以使用相同的密钥(作为 .p8 文件)发送向该 Apple 开发者帐户下的所有 应用推送通知.

APNs Authentication Keys are also really nice by apple because they don't expire, works in both sandbox and production environments, and the same key (as a .p8 file) can be used to send push notifications to all apps under that Apple Developer account.

它还为潜在故障引入了一个新区域:错别字.你可以输入一个随机的 bundle id,只要在 Xcode 中配置了正确的团队",你的应用就会很高兴地获得一个 APNs 设备令牌.

It also introduces a new area for a potential failure: typos. You can type in a random bundle id, and as long as the right "team" is configured in Xcode, your app will happily get an APNs device token.

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

Sending a notification to that device token via APNs (I used this script to send test notifications over HTTP/2 + Auth Keys) will yield a DeviceTokenNotForTopic error, so that should help you figure out what went wrong.

核对清单

  • 确保您的应用程序包 ID 与您要发送到的包 ID 匹配
  • 确保您有一个权利文件,其中至少有一个 aps-environment 键设置为 development(这会在发布版本中由 Xcode 自动为您更新)
  • 如果在 Firebase 等其他 SDK 中使用自动"配置(即 swizzling),请确保您在 application:didRegisterForRemoteNotificationsWithDeviceToken: 中获得 APNs 令牌.这至少确认您的 APNs 设置没问题(但您仍然可能有错字)
  • Ensure your app bundle id matches the bundle id you're sending to
  • Ensure you have an entitlements file, with at least an aps-environment key set to development (this is automatically updated for you in release builds, by Xcode)
  • If using "automatic" configuration (i.e. swizzling) in other SDKs like Firebase, make sure you're getting an APNs token in application:didRegisterForRemoteNotificationsWithDeviceToken:. That at least confirms that your APNs set up is okay (but still you might have a typo)

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

Be sure that the GoogleService-Info.plist file you're using is for the same app as the BUNDLE_ID key in the plist. I've seen developers think that because APNs Keys should work just fine across all of their apps, that the same GoogleService-Info.plist is fine across apps, but that's not the case.

测试

我还建议您使用 FCM 的 HTTP API 来自终端,以帮助调试问题.与 Firebase 通知控制台不同,它会为您提供遇到的任何原始错误.举个例子:

I'd also recommend sending yourself test notifications using FCM's HTTP API from Terminal, to help debug the issue. Unlike the Firebase Notifications Console, it will give you any raw errors it encounters. Here's an example:

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_TOKEN 替换为您的 FCM 令牌.

Fill in your SERVER_KEY with the value in your Firebase Console > Project Settings > Cloud Messaging > Server Key. Replace FCM_TOKEN with your FCM token.

我在处理 FCM SDK 时使用 Paw 向我的应用发送测试通知.

I use Paw to send test notifications to my apps when I'm working on the FCM SDK.

这篇关于推送通知在 Firebase 4.0 中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆