title: Firebase APNS device token not set before retrieving FCM Token for Sender ID - Flutter iOS
body: <p>Not getting notification in iOS using flutter+firebase
  Using <a href="https://pub.dev/packages/connectycube_sdk/example" rel="nofollow noreferrer">connectycube_sdk 2.0.9</a> for calling and chat functionality.</p>
  <p>In console getting below warning -</p>
  <blockquote>
  <p>[FlutterVoipPushNotificationPlugin] voipRegistration</p>
  <p>8.10.0 - [Firebase/Messaging][I-FCM002022] APNS device token not set before retrieving FCM Token for Sender ID '445223936748'.
  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.</p>
  <p>[FlutterVoipPushNotificationPlugin] didUpdatePushCredentials
  credentials.token = {length = 32, bytes = 0xc42015a5 2ba37137 7af02cb4
  e389522d ... d93f5c94 6ce6f0b4 }, type = PKPushTypeVoIP</p>
  <p>[FlutterVoipPushNotificationPlugin]
  handleRemoteNotificationsRegistered notification.userInfo = {
  deviceToken = c42015a52ba371377af02cb4e389522d8104a7a603d15418d93f5c946ce6f0b4; }</p>
  <p>[FlutterVoipPushNotificationPlugin] didUpdatePushCredentials
  credentials.token = {length = 32, bytes = 0xc42015a5 2ba37137 7af02cb4
  e389522d ... d93f5c94 6ce6f0b4 }, type = PKPushTypeVoIP</p>
  <p>[FlutterVoipPushNotificationPlugin]
  handleRemoteNotificationsRegistered notification.userInfo = {
  deviceToken = c42015a52ba371377af02cb4e389522d8104a7a603d15418d93f5c946ce6f0b4; }</p>
  </blockquote>
  <p>Added .p8 and .p12(Production APNs certificate) in firebase console
  AppDelegate file -</p>
  <pre><code>import UIKit
  import Flutter
  import Firebase
  import PushKit
  import CallKit
  import flutter_voip_push_notification
  import flutter_call_kit
  
  @UIApplicationMain
  @objc class AppDelegate: FlutterAppDelegate, PKPushRegistryDelegate {
    override func application(
      _ application: UIApplication,
      didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -&gt; Bool {
      FirebaseApp.configure()
      GeneratedPluginRegistrant.register(with: self)
      self.voipRegistration()
      if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
      }
       application.registerForRemoteNotifications()
      if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
          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()
      return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
  
     // Handle incoming pushes
      public func pushRegistry(_ registry: PKPushRegistry,
                               didReceiveIncomingPushWith payload: PKPushPayload,
                               for type: PKPushType,
                               completion: @escaping () -&gt; Swift.Void){
          print(&quot;didReceiveIncomingPushWith&quot;)
          
          FlutterVoipPushNotificationPlugin.didReceiveIncomingPush(with: payload, forType: type.rawValue)
          
          let signalType = payload.dictionaryPayload[&quot;signal_type&quot;] as! String
          if(signalType == &quot;endCall&quot; || signalType == &quot;rejectCall&quot;){
              return
          }
          
          let uuid = payload.dictionaryPayload[&quot;session_id&quot;] as! String
          let uID = payload.dictionaryPayload[&quot;caller_id&quot;] as! Int
          let callerName = payload.dictionaryPayload[&quot;caller_name&quot;] as! String
          let isVideo = payload.dictionaryPayload[&quot;call_type&quot;] as! Int == 1;
          FlutterCallKitPlugin.reportNewIncomingCall(
              uuid,
              handle: String(uID),
              handleType: &quot;generic&quot;,
              hasVideo: isVideo,
              localizedCallerName: callerName,
              fromPushKit: true
          )
          completion()
      }
      
      // Handle updated push credentials
      public func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
          // Process the received pushCredentials
          FlutterVoipPushNotificationPlugin.didUpdate(pushCredentials, forType: type.rawValue);
      }
      
      // Register for VoIP notifications
      func voipRegistration(){
          // Create a push registry object
          let voipRegistry: PKPushRegistry = PKPushRegistry(queue: DispatchQueue.main)
          // Set the registry's delegate to self
          voipRegistry.delegate = self
          // Set the push type to VoIP
          voipRegistry.desiredPushTypes = [PKPushType.voIP]
      }
      
  }
  </code></pre>
  <p>In main_dev.dart file</p>
  <pre><code>Future&lt;void&gt; main() async {
  
    PrintLog.printLog(&quot;ROOT WIDGET &quot;);
    await runZonedGuarded(() async {
      WidgetsFlutterBinding.ensureInitialized();
      SystemChrome.setPreferredOrientations([
        DeviceOrientation.portraitUp,
      ]);
  
      await Firebase.initializeApp();
      await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
      PushNotificationsManager.instance.init();
     
      FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
  
      NavigatorKey.notifyLaunch = await NavigatorKey.flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
  
      await SharedPref.getInstance();
      HttpOverrides.global = MyHttpOverrides();
      FlavorConfig(
        variables: {
          &quot;env&quot;: &quot;dev&quot;,
          &quot;baseUrl&quot;: &quot;https://humanquestapi.demo.brainvire.dev/api/&quot;,
          &quot;version&quot;: &quot;v1/&quot;,
        },
      );
      Bloc.observer = HomeBlocObserver();
      runApp(const MyApp());
    }, (error, stackTrace) {
      FirebaseCrashlytics.instance.recordError(error, stackTrace);
    });
  }
  </code></pre>
  <p>In PushNotificationManager.dart file</p>
  <pre><code>class PushNotificationsManager {
    static const TAG = &quot;PushNotificationsManager&quot;;
  
    static final PushNotificationsManager _instance =
        PushNotificationsManager._internal();
  
    late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
  
    PushNotificationsManager._internal() {
      Firebase.initializeApp();
      flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
    }
    final FlutterVoipPushNotification _voipPush = FlutterVoipPushNotification();
  
    BuildContext? applicationContext;
  
    static PushNotificationsManager get instance =&gt; _instance;
  
    Future&lt;dynamic&gt; Function(String? payload)? onNotificationClicked;
  
    init() async {
      FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
  
      await firebaseMessaging.requestPermission(
        alert: true,
        announcement: false,
        badge: true,
        carPlay: false,
        criticalAlert: false,
        provisional: false,
        sound: true,
      );
  
      const AndroidInitializationSettings initializationSettingsAndroid =
          AndroidInitializationSettings('ic_launcher_foreground');
      final IOSInitializationSettings initializationSettingsIOS =
          IOSInitializationSettings(
        requestSoundPermission: true,
        requestBadgePermission: true,
        requestAlertPermission: true,
        onDidReceiveLocalNotification: onDidReceiveLocalNotification,
      );
  
      final InitializationSettings initializationSettings =
          InitializationSettings(
              android: initializationSettingsAndroid,
              iOS: initializationSettingsIOS);
      await flutterLocalNotificationsPlugin.initialize(initializationSettings,
          onSelectNotification: onSelectNotification);
  
      String? token;
      if (Platform.isAndroid) {
        firebaseMessaging.getToken().then((token) {
          log('[getToken] token: $token', TAG);
          subscribe(token);
        }).catchError((onError) {
          log('[getToken] onError: $onError', TAG);
        });
      } else if (Platform.isIOS) {
        token = await firebaseMessaging.getAPNSToken();
        log(
          '[getToken] token: $token',
        );
        _initIosVoIP();
      }
  
      if (!isEmpty(token)) {
        subscribe(token);
      }
  
      firebaseMessaging.onTokenRefresh.listen((newToken) {
        subscribe(newToken);
      });
  
      FirebaseMessaging.onMessage.listen((remoteMessage) {
        PrintLog.printLog('[onMessage] message: $remoteMessage');
        // showNotification(remoteMessage);
        if (remoteMessage.data.isNotEmpty &amp;&amp;
            remoteMessage.data[PARAM_SIGNAL_TYPE] != null &amp;&amp;
            remoteMessage.data[PARAM_CALL_TYPE] != null) {
          processCallNotification(remoteMessage.data);
        } else if (remoteMessage.data.isNotEmpty &amp;&amp;
            remoteMessage.data[&quot;message&quot;] != null) {
          showNotification(remoteMessage);
        } else {
          remoteMessage.data.putIfAbsent(&quot;message&quot;, () =&gt; &quot;Notification&quot;);
          showNotification(remoteMessage);
        }
      });
  
      FirebaseMessaging.onBackgroundMessage(onBackgroundMessage);
  
      FirebaseMessaging.onMessageOpenedApp.listen((remoteMessage) {
        PrintLog.printLog('[onMessageOpenedApp] remoteMessage: $remoteMessage');
        if (onNotificationClicked != null) {
          onNotificationClicked!.call(jsonEncode(remoteMessage.data));
        }
      });
    }
  
    _initIosVoIP() async {
      await _voipPush.requestNotificationPermissions();
      _voipPush.configure(onMessage: onMessage, onResume: onResume);
  
      _voipPush.onTokenRefresh.listen((token) {
        log('[onTokenRefresh] VoIP token: $token', TAG);
        subscribe(token);
      });
  
      _voipPush.getToken().then((token) {
        log('[getToken] VoIP token: $token', TAG);
        if (token != null) {
          subscribe(token);
        }
      });
    }
  
    Future&lt;dynamic&gt; onDidReceiveLocalNotification(
        int id, String? title, String? body, String? payload) {
      log('[onDidReceiveLocalNotification] id: $id , title: $title, body: $body, payload: $payload',
          PushNotificationsManager.TAG);
      return Future.value();
    }
  
    Future&lt;dynamic&gt; onSelectNotification(String? payload) {
      log('[onSelectNotification] payload: $payload',
          PushNotificationsManager.TAG);
      if (onNotificationClicked != null) {
        onNotificationClicked!.call(payload);
      }
      return Future.value();
    }
  }
  </code></pre>
  <p>The token we are getting from await firebaseMessaging.getAPNSToken(); is not valid. PFA of Postman</p>
  <p><a href="https://i.stack.imgur.com/ezetj.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ezetj.jpg" alt="enter image description here" /></a></p>
  <p>PFA of Xcode -
  <a href="https://i.stack.imgur.com/x3sKa.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/x3sKa.jpg" alt="enter image description here" /></a></p>
  <p>In android receiving notification but in iOS not receiving notification. How to get proper device token in flutter to get push notification.</p>
  <p>Thanks in advance.!!!</p>