APNS Firebase Notification failed to fetch token

2019-01-21 18:54发布

问题:

For Swift3 / iOS10 see this link:

ios10, Swift 3 and Firebase Push Notifications (FCM)

I'm trying to use the Firebase for Notifications and I integrated it exactly as described in the docs. But I don't understand why is doesn't work. When I build my project I see this line:

2016-05-25 16:09:34.987: <FIRInstanceID/WARNING> Failed to fetch default token Error Domain=com.firebase.iid Code=0 "(null)"

This my AppDelegate:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    FIRApp.configure()
    FIRDatabase.database().persistenceEnabled = true
     var service: DataService = DataService()
    service.start()
    registerForPushNotifications(application)
    application.registerForRemoteNotifications()
    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]])
    }

    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Unknown)
    print("Device Token:", tokenString)
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)  {
    // Print message ID.
    print("Message ID: \(userInfo["gcm.message_id"]!)")

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

回答1:

1.Set Notification Observer in didFinishLaunchingWithOptions Method

2.And Set tokenRefreshNotification method then u get Token in this method.

See below Code

import Firebase
import FirebaseMessaging

override func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
  FIRApp.configure()

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

// NOTE: Need to use this when swizzling is disabled
public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {

  FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox)
}

func tokenRefreshNotification(notification: NSNotification) {
  // NOTE: It can be nil here
  let refreshedToken = FIRInstanceID.instanceID().token()
  print("InstanceID token: \(refreshedToken)")

  connectToFcm()
}

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

public func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
  print(userInfo)
}


回答2:

I too had the same issue and nothing worked for me. But all you have to do is go to your firebase console and then find your project and goto its settings, there check in its cloud messaging tab and upload your .p12 certificate into that.

thats it! happy coding :)



回答3:

1 - Have you correctly configured your certificates as specified in the google documentation ( I won't recall the process here, it is quite long... )? ( https://firebase.google.com/docs/cloud-messaging/ios/certs#configure_an_app_id_for_push_notifications )

2 - I've been through some difficulties when setting up FCM. Once I thought everything was ok but notifications were still not working, I've decided to completely remove the app from the phone, clean my build folder and reinstall the whole thing. After that, it was working.

3 - The app was receiving notifications, but I was still getting the "Failed to fetch default token..." message. It disappeared after a while. Don't ask me why!

This is not really a proper answer, I just share my experience because I know configuring notification is not easy and every clue is welcome. So maybe this one can help. Cheers :)



回答4:

After trying all of the above (and anything I could find elsewhere), what resolves the problem for me is to move

let token = FIRInstanceID.instanceID().token()

to be called when pressing a button, and not on app loading.

I know it's probably not the most elegant solution, but it's good enough for debugging purposes. Im guessing the token is not available immediately by the server, and takes some time to be generated.



回答5:

FCM was working for me then just stopped. I did what Rabs G. suggested and removed the app and installed again and the notifications started working again.



回答6:

The answers above cover most of the issue, but I had the same issue and I found the following info useful:

  1. Firebase can 'rotate' (change) a user's FCM token at any time. This is the 128 character ID that your server will use to send the push notification to the device.

  2. Firebase docs say best practice is to use a delegate to monitor for changes with the delegate callback method:

    - (void)messaging:(nonnull FIRMessaging *)messaging didRefreshRegistrationToken:(nonnull NSString *)fcmToken
    

[Obj - C]

func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String)

[Swift]

The delegate method should be called on every change, at which point you can update the record in your server.

  1. Unfortunately that wasn't working for me, I had a delegate but the callback wasn't being invoked. So I had to resort to manually updating the token on each app launch (as suggested by @micheal chein above) as follows:

    NSString *deviceToken = [FIRInstanceID instanceID].token; // Send this to your server
    

    [Obj-C]

    let token = FIRInstanceID.instanceID().token() // Send this to your server
    

    [Swift]

** Important: update the token after a delay (20-25s), as the rotation can sometimes only reflect after some time. You can use a timer for this.

  1. After this I still get the APNS warning/error message:

    2017-06-06 09:21:49.520: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)"
    

BUT, push notifications work every time without fail. So I think that log message is a bit off (possibly mistimed). If you can get option 2 to work for you, definitely do that!