1

我是Firebase FCM集成的新手,我面臨一些問題。當應用程序第一次安裝時,我沒有收到推送通知,但是如果我打開並關閉應用程序幾次,然後從Firebase發送推送通知,我正在接收通知,而客戶端或服務器代碼沒有任何更改。任何人都可以幫我解決這個問題嗎?Firebase FCM最初不工作,但在應用程序打開後工作3-4次

我附上下面

import UIKit 
import Firebase 
import UserNotifications 
import FirebaseMessaging 
import FirebaseInstanceID 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate,MessagingDelegate { 

    var window: UIWindow? 


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 


     FirebaseApp.configure() 

     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: { (granted, error) in 
        if error == nil{ 
         UIApplication.shared.registerForRemoteNotifications() 
        } 
      }) 
     } else { 
      let settings: UIUserNotificationSettings = 
       UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) 
      application.registerUserNotificationSettings(settings) 
       application.registerForRemoteNotifications() 
     } 

     application.registerForRemoteNotifications() 
     return true 
    } 

    func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) { 
     print("Firebase registration token: \(fcmToken)") 
    } 

    func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) { 
     UIApplication.shared.registerForRemoteNotifications() 
    } 

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 
     // I have tried both method but none worked and i also tried MessagingAPNSTokenType.sandbox and prod 
     // Method 1: Messaging.messaging().apnsToken = deviceToken 
     // Method 2: 
     Messaging.messaging().setAPNSToken(deviceToken, type: MessagingAPNSTokenType.unknown) 
    } 
} 

感謝我的appdelegate代碼提前

回答

3

我有同樣的問題,因爲你並沒有在FCM token並不總是被與APNs device token相關聯的已知問題如果UIApplication.shared.registerForRemoteNotifications()不夠早。

根據this GitHub線程此問題已在FirebaseInstanceID SDK中修復,應該很快推出。

在此期間,您可以:

鎖定您的FirebaseInstanceID pod to 2.0.0在Podfile,或

確保你的應用程序開始打電話UIApplication.shared.registerForRemoteNotifications()FirebaseApp.configure()前最好。

更新:
我只是做了一些額外的測試,我發現這是一個有點亂的時候,這將正常工作。對於某些設備,它立即有一些沒有。對於某些設備Single Token push工作,而不是User Segment。我設法使它工作,這樣你至少通過添加下列得到Single Token pushUser Segment

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
    if #available(iOS 10.0, *) { 
     let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] 
     UNUserNotificationCenter.current().requestAuthorization(
      options: authOptions, 
      completionHandler: {_, _ in 
     }) 

     // For iOS 10 display notification (sent via APNS) 
     UNUserNotificationCenter.current().delegate = self 
     // For iOS 10 data message (sent via FCM) 
     Messaging.messaging().delegate = self 
     application.registerForRemoteNotifications() 
     print("::: registerForRemoteNotifications iOS 10") 

    } else { 
     let settings: UIUserNotificationSettings = 
      UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) 
     application.registerUserNotificationSettings(settings) 
     application.registerForRemoteNotifications() 
     print("::: registerUserNotificationSettings iOS 9") 
    } 

    FirebaseApp.configure() 
    Messaging.messaging().delegate = self 
    Messaging.messaging().shouldEstablishDirectChannel = true 

    if let refreshedToken = InstanceID.instanceID().token() { 
     print("::: InstanceID token: \(refreshedToken)") 
    } 

    NotificationCenter.default.addObserver(self, selector: #selector(tokenRefreshNotification), name: NSNotification.Name.InstanceIDTokenRefresh, object: nil) 
} 

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 
    Messaging.messaging().setAPNSToken(deviceToken, type: .prod) 

    if let refreshedToken = InstanceID.instanceID().token() { 
     print("InstanceID token: \(refreshedToken)") 
    } 
} 

的事情是,它如果你鴕鳥政策訪問didRegisterForRemoteNotificationsWithDeviceToken功能不需額外的工作。

+0

我沒有任何這樣的吊艙。這是我用過的唯一豆莢。 莢「火力地堡/核心」 莢「火力地堡/消息」 請幫助 –

+0

謝謝您的回答,但我發現即使使用您的代碼還我不是從火力地堡接到通知,如果通過針對所有iOS設備模式,但發,如果我將它發送給使用FCM令牌的特定註冊設備,它正在工作。任何想法爲何如此行爲? –

+0

是的,我也一樣,但過了一段時間它也適用於所有設備。我認爲這將在iOS 11中得到解決,所以請稍等,它可能很快就會起作用。 –

0

更新您的appdelegate本

import FirebaseCore 
import FirebaseInstanceID 
import FirebaseMessaging 
import UserNotifications 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate{ 

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
     self.fcmInitialSetup(application) 
     return true 
    } 
    func fcmInitialSetup(_ application: UIApplication){ 

     // [START register_for_notifications] 
     if #available(iOS 10.0, *) { 
      let uns: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) 
      application.registerUserNotificationSettings(uns) 
      application.registerForRemoteNotifications() 

     } else { 
      let settings: UIUserNotificationSettings = 
       UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) 
      application.registerUserNotificationSettings(settings) 
     } 

     application.registerForRemoteNotifications() 

     // [END register_for_notifications] 

     FIRApp.configure() 

     // Add observer for InstanceID token refresh callback. 
     NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotification), name: NSNotification.Name.firInstanceIDTokenRefresh, object: nil) 

     if let token = FIRInstanceID.instanceID().token() { 
      sendTokenToServer(token) 
     } 
    } 

    func sendTokenToServer(_ currentToken: String) { 
     print("sendTokenToServer() Token: \(currentToken)") 
     // Send token to server ONLY IF NECESSARY 

     print("InstanceID token: \(currentToken)") 
     self.token = currentToken 
     UserDefaults.standard.set(self.token, forKey: "token") 
     UserDefaults.standard.synchronize() 
     if self.token != nil{ 
      let userInfo = ["token": self.token] 
      NotificationCenter.default.post(
       name: Notification.Name(rawValue: self.rkey), object: nil, userInfo: userInfo) 
     } 
    } 


    // NOTE: Need to use this when swizzling is disabled 
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 
     let tokenChars = (deviceToken as NSData).bytes.bindMemory(to: CChar.self, capacity: deviceToken.count) 
     var tokenString = "" 

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

     FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.unknown) 
     print("Device Token:", tokenString) 
     print("FIRInstanceID.instanceID().token() Token:", FIRInstanceID.instanceID().token()) 
     if let tokenData = FIRInstanceID.instanceID().token(){ 
      UserDefaults.standard.set(tokenData, forKey: "token") 
      UserDefaults.standard.synchronize() 
      let userInfo = ["token": tokenData] 
     } 
    } 

    func tokenRefreshNotification(_ notification: Notification) { 
     // NOTE: It can be nil here 
     //  print("Token:\(FIRInstanceID.instanceID().token()!)") 
     if let refreshedToken = FIRInstanceID.instanceID().token() { 
      print("InstanceID token: \(refreshedToken)") 
      UserDefaults.standard.set(refreshedToken, forKey: "token") 
      UserDefaults.standard.synchronize() 
      print("update now \(self.token)") 
      if self.token != nil{ 
       let userInfo = ["token": self.token] 
       NotificationCenter.default.post(
        name: Notification.Name(rawValue: self.rkey), object: nil, userInfo: userInfo) 
      } 

     } 

     // Connect to FCM since connection may have failed when attempted before having a token. 
     connectToFcm() 
    } 
    // [END refresh_token] 
    func connectToFcm() { 
     FIRMessaging.messaging().connect { (error) in 
      if (error != nil) { 
       print("Unable to connect with FCM. \(error)") 
      } else { 
       print("Connected to FCM.") 
      } 
     } 
    } 

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) { 
     print(userInfo) 
    } 

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { 
     print("Within open URL") 
     return true 
    } 


    // [START receive_apns_token_error] 
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError 
     error: Error) { 
     print("Registration for remote notification failed with error: \(error.localizedDescription)") 
     // [END receive_apns_token_error] 
     let userInfo = ["error": error.localizedDescription] 
     NotificationCenter.default.post(
      name: Notification.Name(rawValue: rkey), object: nil, userInfo: userInfo) 
    } 

    func registrationHandler(_ token: String!, error: NSError!) { 
     if (token != nil) { 
      self.token = token! 
      print("Registration Token: \(self.token)") 
      UserDefaults.standard.set(self.token, forKey: "token") 
      UserDefaults.standard.synchronize() 
      let userInfo = ["token": self.token] 
      NotificationCenter.default.post(
       name: Notification.Name(rawValue: self.rkey), object: nil, userInfo: userInfo) 
     } else { 
      print("Registration to GCM failed with error: \(error.localizedDescription)") 
      let userInfo = ["error": error.localizedDescription] 
      NotificationCenter.default.post(
       name: Notification.Name(rawValue: self.rkey), object: nil, userInfo: userInfo) 
     } 
    } 

    func registerForPushNotifications(_ application: UIApplication) { 
     let notificationSettings = UIUserNotificationSettings(
      types: [.badge, .sound, .alert], categories: nil) 
     application.registerUserNotificationSettings(notificationSettings) 
    } 

    func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) { 
     if notificationSettings.types != UIUserNotificationType() { 
      application.registerForRemoteNotifications() 
     } 
    } 

    // [START receive_message] 
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], 
        fetchCompletionHandler completionHandler: @escaping (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. add Toast 
     print(userInfo); 

     print(application.keyWindow?.visibleViewController() ?? "") 

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


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



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

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

    func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { 

    } 
} 
// [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, 
           willPresent notification: UNNotification, 
           withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { 
     let userInfo = notification.request.content.userInfo 
     // Print message ID. 
     print("Message ID: \(userInfo["gcm.message_id"]!)") 
     // Print message ID. add Toast 

     // Print full message. 
     print("%@", userInfo) 
     // Print full message. 
     print("%@", userInfo) 
    } 
} 

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

NotificationCenter.default.addObserver(自我選擇:#selector(self.getFcmToken),名稱:。firInstanceIDTokenRefresh, 對象:無)

把這個應用程序也finsih推法 並進行功能

FUNC getFcmToken(通知:NSNotification){

guard let contents = FIRInstanceID.instanceID().token() 
     else { 
      return 
    } 
    print("InstanceID token: \(contents)") 
    if let token = FIRInstanceID.instanceID().token(){ 
     print(token) 

}

相關問題