david vargas
david vargas

Reputation: 333

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

Upvotes: 19

Views: 55133

Answers (10)

M hassan malik
M hassan malik

Reputation: 1

My issue was resolved by adding onRegister() inside PushNotification.configure(). I was not setting the retrieved APNS token in messaging() before asking for the FCM token.

onRegister(token) {
  if (Platform.OS === 'ios') {
    messaging().setAPNSToken(token.token);
  }
}

Upvotes: 0

Micro
Micro

Reputation: 10891

One thing that worked for me on a physical device was going to the iPhone settings -> your app -> turning the Allow Notifications button off and on and then relaunching the app.

Upvotes: 1

boby dhorajiya
boby dhorajiya

Reputation: 49

The issue is related to permission,First you have to ask for permission then we get token :

FirebaseMessaging.instance.requestPermission().then((value) {
FirebaseMessaging.instance.getToken().then((value) {
  print('TOken$value');
});

});

Upvotes: 0

Octave
Octave

Reputation: 444

Error in the logs of the phone/simulator

2023-01-28 21:11:53.907821+0100 App[16955:1733197] 10.4.0 - [FirebaseMessaging][I-FCM002022] APNS device token not set before retrieving FCM Token for Sender ID 'XXXXXXXXX'.Be sure to re-retrieve the FCM token once the APNS device token is set.
2023-01-28 21:11:53.908157+0100 App[16955:1733197] 10.4.0 - [FirebaseMessaging][I-FCM002022] Declining request for FCM Token since no APNS Token specified
⚡️  WebView loaded
⚡️  [log] - AppModule, running the app code.
⚡️  [log] -

The token must be set on the messaging component.

In AppDelegate.swift, you must have the following handler

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
}

with this instruction

Messaging.messaging().apnsToken = deviceToken

Full code is

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  Messaging.messaging().apnsToken = deviceToken
  Messaging.messaging().token(completion: { (token, error) in
    if let error = error {
        NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
    } else if let token = token {
        NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: token)
    }
  })
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
  NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
}

This is explained in the documentation of the Ionic framework, detailing how to setup Firebase Messaging for iOS.

https://capacitorjs.com/docs/guides/push-notifications-firebase#add-initialization-code

Note - with this setup, notification will work on both the iOS Simulator provided by XCode and native devices.

Upvotes: 2

Igor Josevski
Igor Josevski

Reputation: 1

I hope this will help to someone, I had the same issue, and after long debugging and reading a lot of posts, this is the solution that worked for me: (Worked on real device on WiFi (no sim))

In Pods file:

target 'YOUR APP' do
  config = use_native_modules!
  
  pod 'FirebaseCore', :modular_headers => true
  pod 'Firebase', :modular_headers => true
  pod 'FirebaseMessaging', :modular_headers => true
  pod 'FirebaseCoreInternal', :modular_headers => true
  pod 'GoogleUtilities', :modular_headers => true
  $RNFirebaseAsStaticFramework = true

Then in AppDelegate.h

#import <UserNotifications/UNUserNotificationCenter.h>
#import <RNFBMessaging+FIRMessagingDelegate.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UIApplicationDelegate,UNUserNotificationCenterDelegate, FIRMessagingDelegate>

@property (nonatomic, strong) UIWindow *window;

Then in AppDelegate.mm

@implementation AppDelegate

- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
    NSLog(@"FCM registration token: %@", fcmToken);
    // Notify about received token.
    NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"];
    [[NSNotificationCenter defaultCenter] postNotificationName:
     @"FCMToken" object:nil userInfo:dataDict];
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
      NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
      NSLog(@"This is device token%@", deviceToken);
    //NSString *deviceTokenString = [deviceToken description];
    [FIRMessaging messaging].APNSToken = deviceToken;
  
}


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  
  [FIRApp configure];
  [[UIApplication sharedApplication] registerForRemoteNotifications];

  RCTAppSetupPrepareApp(application);

  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  
  
//...OTHER CODE HERE

  [UNUserNotificationCenter currentNotificationCenter].delegate = self;
  UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
      UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
  [[UNUserNotificationCenter currentNotificationCenter]
      requestAuthorizationWithOptions:authOptions
      completionHandler:^(BOOL granted, NSError * _Nullable error) {
        // ...
      }];

   
   [[FIRMessaging messaging] setDelegate:self];
  return YES;
}

Upvotes: 0

This might be late, but the error

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.

was sorted for me by adding this

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        print("Yay! Got a device token 🥳 \(deviceToken)")
        Messaging.messaging().setAPNSToken(deviceToken, type: .unknown)
    } 

Upvotes: 8

kamranbekirovyz
kamranbekirovyz

Reputation: 1331

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.

Upvotes: 0

Siddharth Kamaria
Siddharth Kamaria

Reputation: 2717

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.

Upvotes: 4

David
David

Reputation: 171

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.

Upvotes: 5

babibo
babibo

Reputation: 349

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.

Upvotes: 6

Related Questions