APNS Firebase Notification failed to fetch token

26,582

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

Solution 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 :)

Solution 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 :)

Solution 4

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!

Solution 5

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.

Share:
26,582
Dmitry Kuzin
Author by

Dmitry Kuzin

Updated on June 06, 2020

Comments

  • Dmitry Kuzin
    Dmitry Kuzin almost 4 years

    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)
    }
    
  • Rabs G
    Rabs G over 7 years
    I had issues with FCM and removing the app and then clean and build the project worked for me.
  • Uma Madhavi
    Uma Madhavi over 7 years
    Even after doing some many times this trick didn't work for me.
  • iAkshay
    iAkshay over 7 years
    Initially I've added only development cert on firebase console. Even then I was getting the error. Then I add production certificate too, which let registration successful and grant the token. So according to my case, we need both certs. added to firebase console.
  • mythicalcoder
    mythicalcoder over 7 years
    I had to do this. Let me check now after uploading.
  • RoyBS
    RoyBS over 7 years
    I had the same issue, my problem was that tried to register for notification before calling FIRApp.configure() (for no good reason). when I changed that I got the token in the AppDelegate
  • Admin
    Admin over 7 years
    Wow, thank you so much! I called FIRApp.configure() in appDelegate, and tried fetching the token in the first view controller's viewDidLoad. it never occurred to me the FIRApp.configure was not called. I moved my code (simply updating the token to my server) to appDelegate, and it works perfectly. :)
  • Peza
    Peza almost 7 years
    Rotation of the FCM token can happen after: The app is restored on a new device; the user uninstalls/reinstall the app; the user clears app data.