'Error APNS device token not set before retrieving FCM Token for Sender ID

I am receiving messages from firebase for notifications with APNs. In firebase, I have the certificate of APNs key, with the same id in the Xcode project in Firebase that is extracted from Apple Developer.

But I don't know why this could be happening and I get this error and it is registering two tokens in the Messaging extension:

extension AppDelegate : MessagingDelegate {
  func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {}}

APNS device token not set before retrieving FCM Token for Sender ID '########'. Notifications to this FCM Token will not be delivered over APNS.Be sure to re-retrieve the FCM token once the APNS device token is set.

Added what I have in the AppDelegate

import Firebase
import MasivPushIosSdk

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate{

    var firebaseToken: String = ""
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        FirebaseApp.configure()
        self.registerForFirebaseNotification(application: application)
        Messaging.messaging().delegate = self
        return true
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
    }

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

        application.registerForRemoteNotifications()
    }
    
}

extension AppDelegate: MessagingDelegate, UNUserNotificationCenterDelegate {

//MessagingDelegate
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        self.firebaseToken = fcmToken!
        print("Firebase token: \(fcmToken)")
    }

    //UNUserNotificationCenterDelegate
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("APNs received with: \(userInfo)")
     }
}


Solution 1:[1]

This is a simulator only log. You can safely ignore it. The reason you get this is that Firebase tries to create a mapping from the FCM token to the APNS token so it can send the APNS messages to the iOS devices. However, there is no APNS token on the simulator so the mapping fails.

Try testing it on an actual device to see if you still get the error.

Solution 2:[2]

I spent a long time on this issue. I finally got it working with remote messages.

It can be caused by a few main reasons.

  1. GoogleService-Info.plist wasn't added to your project through xcode (checkmark copy over files if needed)
  2. GoogleService-Info.plist should show up in Build Phases -> Copy Bundle Resources. If 1 is done, it would be here automatically.
  3. (If you are working with React Native) Make sure your GoogleService-Info.plist info points to the same Firebase Project that your Javascript code has.
  4. Apple Service Keys, and firebase project where this key is used should point to the same apple bundle identifier.
  5. (If you are working with React Native) Put this in componentDidMount()
const authStatus = await firebase.messaging().requestPermission();
  if (authStatus === 1) {
    let fcmToken = await firebase.messaging().getToken();
    if (fcmToken) {
      console.log('Firebase Push Token is:', fcmToken);
    } 
  }
  1. Finally make sure your Device can connect to the internet properly. I was stuck here, my iPhone X had 2 of 3 bars, but did not connect to the internet while using same wifi as my development laptop. My laptop had no issues so I assumed my phone was connecting also ok. More than a day was wasted because I assumed. So, just double check your phone's connection works.

For more info: A) If working Natively: https://firebase.google.com/docs/cloud-messaging/ios/client B) If using React Native: https://rnfirebase.io/messaging/usage/ios-setup

Note: Do not mix A and B. One is meant for native IOS, other is React Native.

p.s. I added React native since i came across your question in my searches while using it.

Solution 3:[3]

Make sure you don't rename the auth key file

In my case, I had renamed the auth key file to something else and that was causing the issue. I tried naming it back to the default format AuthKey_<KeyID>.p8 and everything started working.

Solution 4:[4]

In our case, we noticed a log above of it:

The project's Bundle ID is inconsistent with either the Bundle ID in 'GoogleService-Info.plist'

So, the case was: our app's Bundle Identifier was different from which we used to create iOS app for our Firebase project.

Making them same, solved the issue.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 babibo
Solution 2
Solution 3 Siddharth Kamaria
Solution 4 kamranbekirovyz