Firebase - 推送通知 - 没有按预期工作

Posted

技术标签:

【中文标题】Firebase - 推送通知 - 没有按预期工作【英文标题】:Firebase - Push Notifications - Not quite working as expected 【发布时间】:2018-11-29 03:14:44 【问题描述】:

为了尝试使用 Firebase 推送通知,我一直在关注以下三个文档: One、Two、Three 和 Four。

我有一个问题,但在问之前;这是我能看到的:

当我的应用在前台并发送通知时,仅调用此函数:

userNotificationCenter(_:willPresent:withCompletionHandler:)

如果我点击通知,那么这个也是所谓的:

userNotificationCenter(_:didReceive:withCompletionHandler:)

当我的应用程序在后台并发送通知时,不会调用任何内容。

如果我点击通知,则会调用此通知:

userNotificationCenter(_:didReceive:withCompletionHandler:)

由于这种情况,无需做出反应(通过点击通知);当通知在前台到达时,我可以让应用程序执行一些有用的操作,使用 userNotificationCenter(_:willPresent:withCompletionHandler:) 函数。

另一方面,在后台,如果用户点击通知,我只能在通知到达时让应用执行一些有用的操作。

我有没有办法让应用程序执行一些有用的操作,即使用户没有反应?

这是我此时的相关代码:

import UIKit
import Firebase
import UserNotifications
import FirebaseInstanceID
import FirebaseMessaging


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate 
    var window: UIWindow?

    func application(_ application: UIApplication, 
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
        window = UIWindow(frame: UIScreen.main.bounds)

        UNUserNotificationCenter.current().delegate = self
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: 
                granted, error in
                if error != nil print("Error: \(error!)")

                if granted 
                    DispatchQueue.main.async
                        application.registerForRemoteNotifications()
                
        )

        FirebaseApp.configure()
        .......

        return true
    


    func application(_ application: UIApplication,
                     didReceiveRemoteNotification userInfo: [AnyHashable: Any]) 
        print(#function)
        if let messageID = userInfo[gcmMessageIDKey] 
            print("Message ID: \(messageID)")
        

        // Print full message.
        print(userInfo)
    


    func application(_ application: UIApplication,
                     didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) 
        print(#function)
        if let messageID = userInfo[gcmMessageIDKey] 
            print("Message ID: \(messageID)")
        

        // Print full message.
        print(userInfo)

        completionHandler(UIBackgroundFetchResult.newData)
    

有关信息,我使用的是 Xcode 版本 10.1、ios 12.1 和 Swift 4.2。

【问题讨论】:

【参考方案1】:

swift 4.2、Xcode 10.0、IOS 12.0

import UIKit
import Firebase
import UserNotifications
import FirebaseInstanceID
import FirebaseMessaging

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate 
    var window: UIWindow?

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
        window = UIWindow(frame: UIScreen.main.bounds)

        if #available(iOS 10.0, *) 
            let center = UNUserNotificationCenter.current()
            center.requestAuthorization(options: [.badge, .alert , .sound])  (granted, error) in
                let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound]
                let setting = UIUserNotificationSettings(types: type, categories: nil)
                UIApplication.shared.registerUserNotificationSettings(setting)
                UIApplication.shared.registerForRemoteNotifications()
            
         else 
            let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound]
            let setting = UIUserNotificationSettings(types: type, categories: nil)
            UIApplication.shared.registerUserNotificationSettings(setting)
            UIApplication.shared.registerForRemoteNotifications()
        

        application.registerForRemoteNotifications()

        if(FIRApp.defaultApp() == nil)
            FIRApp.configure()
        
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(self.tokenRefreshNotification(notification:)),
                                               name: NSNotification.Name.firInstanceIDTokenRefresh,
                                               object: nil)

        return true
    


    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) 
        let userInfo = response.notification.request.content.userInfo as? NSDictionary
        _ = UIStoryboard(name: "Main", bundle: nil)
        let appdelegate = UIApplication.shared.delegate as! AppDelegate
        let aps = userInfo?["aps"] as! NSDictionary
    

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 
        completionHandler([.alert, .badge, .sound])
    


func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) 
    // Convert token to string

    let deviceTokenString = deviceToken.reduce("", $0 + String(format: "%02X", $1))
    print("Device Token", deviceTokenString)
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.unknown)


func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) 
    let appdelegate = UIApplication.shared.delegate as! AppDelegate
    let aps = data["aps"] as! NSDictionary
    let state = UIApplication.shared.applicationState
    if state == .background 
    
    if state == .active 
    


//MARK: Notification Center Call
func callNotificationCenter()
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadData"), object: nil)


func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) 


// start firebase
@objc func tokenRefreshNotification(notification: NSNotification) 
    let refreshedToken = FIRInstanceID.instanceID().token()
    print(refreshedToken)
    connectToFcm()


func connectToFcm() 
    FIRMessaging.messaging().connect  (error) in
        if (error != nil) 
            print("Unable to connect with FCM. \(error?.localizedDescription ?? "")")

         else 
            print("Connected to FCM")
        
    

【讨论】:

好的。那么当应用处于后台并且用户什么都不做时,当通知到达时,将调用这段代码中的哪个函数? didReceiveRemoteNotification 感谢您的回复。我很快尝试编译您的代码以查看它是如何工作的,但它似乎使用了比我的更旧的 API(可能是因为您使用的 pod 更旧)。您能否在我的代码中指出我需要更改哪些内容才能使事情按我想要的方式工作? 使用最新的 Pod。 是的,我想这就是我正在做的事情。

以上是关于Firebase - 推送通知 - 没有按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

IOS Firebase 云功能中未收到推送通知

firebase react-native 推送通知适用于 iOS 发布版本,但不适用于通过 App Store 发布的应用程序

Firebase - 推送通知 - 不工作

IOS Firebase 云消息传递“InvalidApnsCredential”

在应用程序被杀死后,使用 HTTP 请求通过 Firebase(FCM)向 iOS 设备发送推送通知 [重复]

Firebase FCM 推送通知停止工作 iOS 11.1.1