Отключение приложения для обмена облачными сообщениями

У меня есть приложение, которое хранит пользовательский сеанс в NSUserDefaults. Когда приложение принудительно закрывается, вначале проверьте, есть ли сеанс пользователя контроллера данных, если он отправлен в начальное окно следующим образом:

override func viewWillAppear(animated: Bool) {

    self.view.hidden = true

    let defaults = NSUserDefaults.standardUserDefaults()
    if   defaults.stringForKey("user") != nil
    {

        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            let viewController:UIViewController = self.storyboard?.instantiateViewControllerWithIdentifier("vistaInicio") as! ViewControllerInicio
            self.presentViewController(viewController, animated: true, completion: nil)
        })


    }else
    {
    self.view.hidden = false

    }

}

Это работало гладко до сегодняшнего дня, когда я решил реализовать push-уведомления с обновлением firebase после этого учебника Настройка клиентского приложения CloudBase Firebase для iOS. Проблема возникает, когда он убил приложение и снова вводит следующий код ошибки:

 2016-05-19 16:05:27.647: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(full)"
 2016-05-19 16:05:27.659: <FIRMessaging/INFO> FIRMessaging library version 1.1.0
 2016-05-19 16:05:27.831: <FIRMessaging/WARNING> FIRMessaging registration is not ready with auth credentials
Unable to connect with FCM. Optional(Error Domain=com.google.fcm Code=501 "(null)")

Снимок экрана

Ответ 1

Вот решение,

Сначала Загрузите необходимые сертификаты в Firebase Console. Затем в вашем приложении включите Push Notifications и Background Modes → Remote Notifications

После этого в App Delegate используйте код ниже (я указываю сложную строку):

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    registerForPushNotifications(application)
    // Override point for customization after application launch.
    // Use Firebase library to configure APIs
    FIRApp.configure()
    return true
}

func registerForPushNotifications(application: UIApplication) {
    let notificationSettings = UIUserNotificationSettings(
        forTypes: [.Badge, .Sound, .Alert], categories: nil)
    application.registerUserNotificationSettings(notificationSettings)
}

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
    if notificationSettings.types != .None {
        application.registerForRemoteNotifications()
    }
}

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]])
    }

    //Tricky line
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Unknown)
    print("Device Token:", tokenString)
}

Ответ 2

Не забывайте в AppDelegate:

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

    registerForPushNotifications(application)
    FIRApp.configure()

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

    // Override point for customization after application launch.
    return true
  }

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


  func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
                   fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    print("===== didReceiveRemoteNotification ===== %@", userInfo)
  }


 func tokenRefreshNotificaiton(notification: NSNotification) {
    let refreshedToken = FIRInstanceID.instanceID().token()!
    print("InstanceID token: \(refreshedToken)")

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

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

Пожалуйста, убедитесь, что вы также можете сделать в Info.plist: FirebaseAppDelegateProxyEnabled = NO

Я пока не знаю, но я получил print(...) в didReceiveRemoteNotification, но не получаю всплывающее окно. Я отправляю сообщение из Firebase → Console → Notification → Single device и копирует здесь токен, который я получил из консоли Xcode → func tokenRefreshNotificaiton

Ответ 3

Ответ правильный, это шаги, но также проверьте время своего устройства. Поскольку, если ваше время и дата слишком удалены, он не будет работать

Ответ 4

После того, как триплер проверил всю интеграцию, для меня проблема заключалась в том, что тест имел дату, измененную на неделю вперед. Вероятно, FCM SDK выполняет некоторые проверки на основе даты.

Ошибка может быть менее общей на стороне Firebase, так как я потерял почти день, ища решение. Надеюсь, это поможет.