简体   繁体   English

Firebase iOS 推送通知在首次安装时不起作用

[英]Firebase iOS Push Notifications not working on first install

When I first install and open the app and accept the notifications permission alert from Apple, I get this log from Firebase:当我第一次安装并打开应用程序并接受来自 Apple 的通知权限警报时,我从 Firebase 获得以下日志:

5.16.0 - [Firebase/InstanceID][I-IID023004] Could not update attributes of the key pair to be accessible after first unlock. 5.16.0 - [Firebase/InstanceID][I-IID023004] 无法更新密钥对的属性,使其在首次解锁后可访问。 update status: -25300更新状态:-25300

After that, if I close or send the app to the background I don't receive any notifications.之后,如果我关闭应用程序或将应用程序发送到后台,我将不会收到任何通知。 If I open the app a second time, then notifications start working normally.如果我第二次打开应用程序,通知就会开始正常工作。

This is my current setup:这是我目前的设置:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    setupPushNotificationsHandling(application)
    return true
}

private func setupPushNotificationsHandling(_ application: UIApplication) {
    UNUserNotificationCenter.current().delegate = self
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, _) in
        guard granted else { return }

        DispatchQueue.main.async {
            application.registerForRemoteNotifications()

            FirebaseApp.configure()
            InstanceID.instanceID().instanceID { (result, _) in
                // Receive notifications from the "all" topic
                Messaging.messaging().subscribe(toTopic: "all")
            }
        }
    }
}

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    print("response \(response)")
    completionHandler()
}

This is how I solved it. 这就是我解决的方法。

  1. Before attempting to subscribe to a notifications topic, I wait until the delegate method application:didRegisterForRemoteNotificationsWithDeviceToken: is called. 在尝试订阅通知主题之前,我要等到委托方法application:didRegisterForRemoteNotificationsWithDeviceToken:被调用。
  2. I retry until the call InstanceID.instanceID().instanceID returns a valid device token. 我重试,直到调用InstanceID.instanceID().instanceID返回有效的设备令牌。

Complete setup: 完成设置:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    setupPushNotificationsHandling(application)
    return true
}

private func setupPushNotificationsHandling(_ application: UIApplication) {
    FirebaseApp.configure()

    application.registerForRemoteNotifications()

    UNUserNotificationCenter.current().delegate = self
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { (_, _) in }
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // Receive notifications from the "all" topic
    subscribeToNotificationsTopic(topic: "all")
}

func subscribeToNotificationsTopic(topic: String) {
    // Retry until the notifications subscription is successful
    DispatchQueue.global().async {
        var subscribed = false
        while !subscribed {
            let semaphore = DispatchSemaphore(value: 0)

            InstanceID.instanceID().instanceID { (result, error) in
                if let result = result {
                    // Device token can be used to send notifications exclusively to this device
                    print("Device token \(result.token)")

                    // Subscribe
                    Messaging.messaging().subscribe(toTopic: topic)

                    // Notify semaphore
                    subscribed = true
                    semaphore.signal()
                }
            }

            // Set a 3 seconds timeout
            let dispatchTime = DispatchTime.now() + DispatchTimeInterval.seconds(3)
            _ = semaphore.wait(timeout: dispatchTime)
        }
    }
}

I have met the same problem and solved using @AlejandroCotilla's answer.我遇到了同样的问题并使用@AlejandroCotilla 的答案解决了。 Please note that with Firebase ver 8.10.0, "InstanceID.instanceID().instanceID .." has been rename to "Installations.installations().installationID ..".请注意,在 Firebase 8.10.0 版中,“InstanceID.instanceID().instanceID ..”已重命名为“Installations.installations().installationID ..”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM