【问题标题】:ios10, Swift 3 and Firebase Push Notifications (FCM)ios10、Swift 3 和 Firebase 推送通知 (FCM)
【发布时间】:2017-02-05 08:32:58
【问题描述】:

我很难显示我从 FCM 通知控制台发送到我的设备的推送通知。我可以看到设备正在接收通知,因为我可以看到我发送的消息“test8”

Connected to FCM.
%@ [AnyHashable("notification"): {
    body = test8;
    e = 1;
},

但不管我的应用是在前台还是后台,我都不会显示通知。

我在 info.plist 中添加了“必需的后台模式 - 应用下载内容以响应推送通知”。我的证书是正确的,生成令牌没有问题。我的应用正在接收通知,但只是不显示它们。

import UIKit
import UserNotifications
import Firebase
import FirebaseInstanceID
import FirebaseMessaging

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        // [START register_for_notifications]
        if #available(iOS 10.0, *) {
            let authOptions : UNAuthorizationOptions = [.Alert, .Badge, .Sound]
            UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions(
                authOptions,
                completionHandler: {_,_ in })

            // For iOS 10 display notification (sent via APNS)
            UNUserNotificationCenter.currentNotificationCenter().delegate = self
            // For iOS 10 data message (sent via FCM)
            FIRMessaging.messaging().remoteMessageDelegate = self

        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
        }

        application.registerForRemoteNotifications()

        // [END register_for_notifications]

        FIRApp.configure()

        // Add observer for InstanceID token refresh callback.
        NSNotificationCenter.defaultCenter().addObserver(self,
                                                         selector: #selector(self.tokenRefreshNotification),
                                                         name: kFIRInstanceIDTokenRefreshNotification,
                                                         object: nil)

        return true
    }

    // [START receive_message]
    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
                     fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
        // If you are receiving a notification message while your app is in the background,
        // this callback will not be fired till the user taps on the notification launching the application.
        // TODO: Handle data of notification

        // Print message ID.
        print("Message ID: \(userInfo["gcm.message_id"]!)")

        // Print full message.
        print("%@", userInfo)
    }
    // [END receive_message]

    // [START refresh_token]
    func tokenRefreshNotification(notification: NSNotification) {
        if let refreshedToken = FIRInstanceID.instanceID().token() {
            print("InstanceID token: \(refreshedToken)")
        }

        // Connect to FCM since connection may have failed when attempted before having a token.
        connectToFcm()
    }
    // [END refresh_token]

    // [START connect_to_fcm]
    func connectToFcm() {
        FIRMessaging.messaging().connectWithCompletion { (error) in
            if (error != nil) {
                print("Unable to connect with FCM. \(error)")
            } else {
                print("Connected to FCM.")
            }
        }
    }
    // [END connect_to_fcm]

    func applicationDidBecomeActive(application: UIApplication) {
        connectToFcm()
    }

    // [START disconnect_from_fcm]
    func applicationDidEnterBackground(application: UIApplication) {
        FIRMessaging.messaging().disconnect()
        print("Disconnected from FCM.")
    }
    // [END disconnect_from_fcm]
}

// [START ios_10_message_handling]
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {

    // Receive displayed notifications for iOS 10 devices.
    func userNotificationCenter(center: UNUserNotificationCenter,
                                willPresentNotification notification: UNNotification,
                                withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo
        // Print message ID.
        print("Message ID: \(userInfo["gcm.message_id"]!)")
        // Print full message.
        print("%@", userInfo)
    }
}

extension AppDelegate : FIRMessagingDelegate {
    // Receive data message on iOS 10 devices.
    func applicationReceivedRemoteMessage(remoteMessage: FIRMessagingRemoteMessage) {
        print("%@", remoteMessage.appData)
    }
}
// [END ios_10_message_handling]

我一直在尝试自己研究和解决这个问题,但我遇到了问题。任何帮助或建议将不胜感激。

【问题讨论】:

  • 你解决了你的问题吗,我没有在 Xcode 8.1 swift 2.3 中收到通知。因为这几天我正在尝试从服务器端收到通知,而且当我发送 firebase 控制台时我收到了。请你能帮帮我吗?

标签: ios swift firebase firebase-cloud-messaging


【解决方案1】:

对我来说这是缺少的entitlements 文件,所以在您项目的Capabilities 中,您必须单击修复问题。 Xcode 将为您设置文件。

【讨论】:

  • 我认为这将是大多数 Xcode 8+ 用户的解决方案!干杯
【解决方案2】:

你需要移动

 application.registerForRemoteNotifications()

它不应该在 else 中。

// [START register_for_notifications]
    if #available(iOS 10.0, *) {
        let authOptions : UNAuthorizationOptions = [.Alert, .Badge, .Sound]
        UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions(
            authOptions,
            completionHandler: {_,_ in })

        // For iOS 10 display notification (sent via APNS)
        UNUserNotificationCenter.currentNotificationCenter().delegate = self
        // For iOS 10 data message (sent via FCM)
        FIRMessaging.messaging().remoteMessageDelegate = self

    } else {
        let settings: UIUserNotificationSettings =
            UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
        application.registerUserNotificationSettings(settings)            
    }

application.registerForRemoteNotifications()

See following commit in Firebase

【讨论】:

  • 是的,这解决了我的问题!!必须更新原始源代码!!
  • 谢谢,也解决了我的问题。但是,您应该为 swift 3 更新您的代码。
【解决方案3】:

didRegisterForRemoteNotificationsWithDeviceToken方法内,添加如下代码:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
    var tokenString = ""

    for i in 0..<deviceToken.length {
        tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
    }

    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Unknown)

    print("tokenString: \(tokenString)")
}

别忘了在Capabilities中启用Push Notifications

【讨论】:

  • 我添加了以下内容,因为我使用的是 swift 语法,但它并没有解决我遇到的问题。不过我很欣赏这个建议。 func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.sandbox) }
  • @Paul_D 将此行添加到您的 Info.plist 文件中:FirebaseAppDelegateProxyEnabled 并将布尔值设置为 NO
  • @Paul_D 是的,保罗,在这里提供帮助有点困难,因为您需要执行几个步骤。我做了一个带有教程的视频,但它是葡萄牙语的,它还没有在网络上。但是您是否在应用程序中导入了 Firebase 生成的 JSON?
  • Gustavo 我按照您的指示进行操作,现在通知正在工作。我必须按照你的指示,然后我从我的设备上卸载了该应用程序,清理了项目,重建,然后在我的手机上重新安装了它。我现在可以在我的应用程序在前台和后台运行时接收通知。谢谢您的帮助。我真的很感激。
  • 有人把它转换成 Swift 3 代码吗?错误:无法使用类型为 '(UnsafeRawPointer)' 的参数列表调用类型为 'UnsafePointer' 的初始化程序 - 所以 UnsafeRawPointer 有一种全新的方法
猜你喜欢
  • 2017-10-10
  • 2022-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多