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) 

}

相关问题