Karthikeyan P
Karthikeyan P

Reputation: 475

Flutter FCM iOS Issue - APNS device token not set before retrieving FCM Token

I am using firebase_messaging v9.0.1 in my Flutter application. On configuring this library based on the https://pub.dev/packages/firebase_messaging/example, I am able to receive the notification for android in both foreground and background states. But the same for iOS is not working. I am getting the below 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.

My iOS device is connected to internet and there were no network related issues while running this.

Do I want to call any other function apart from FirebaseMessaging.instance.getToken() for iOS? Please help.

Thanks.

Upvotes: 9

Views: 20877

Answers (4)

mdaniels
mdaniels

Reputation: 1

I received this error too but in my case I had set up an APN certificate instead of an APN key in Firebase. I had to update my APN certificate in Firebase which had expired. This resolved the error and I could obtain a token with .getToken() in my app.

Update: In Firebase > Project Settings > Cloud Messaging I uploaded an APNs Authentication Key for my flutter iOS app. I did not upload any APNs Certificates. Follow guide here on how to create and upload APN Authentication key: https://firebase.flutter.dev/docs/messaging/apple-integration/

Then in my flutter project I use this to get FCM token

import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';


Future<String?> getFirebaseToken() async {
  String? fcmToken;
  if (Platform.isIOS) {
    // On iOS we need to see an APN token is available first
    String? apnsToken = await FirebaseMessaging.instance.getAPNSToken();
    if (apnsToken != null) {
      fcmToken = await FirebaseMessaging.instance.getToken();
    }
    else {
      // add a delay and retry getting APN token
      await Future<void>.delayed(const Duration(seconds: 3,));
      apnsToken = await FirebaseMessaging.instance.getAPNSToken();
      if (apnsToken != null) {
        fcmToken = await FirebaseMessaging.instance.getToken();
      }
    }
  }
  else {
    // android platform
    fcmToken = await FirebaseMessaging.instance.getToken();
  }
  return fcmToken;
}

In my main.dart I initialise firebase like this

  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  FirebaseMessaging.instance.onTokenRefresh.listen((String token) {
    String? fcmToken = await getFirebaseToken();
    // save token to storage or server-side depending where you want 
    // to send push notification
  })

Upvotes: 0

Ezra
Ezra

Reputation: 11

The way I solve this issue, instead of running the application thru debug mode, I archive the app and download it thru ad hoc and somehow this solves the issue

Upvotes: 1

Vettiyanakan
Vettiyanakan

Reputation: 8520

Try running on a real device

Try this:

AppDelegate.swift

import UIKit
import Flutter
import Firebase
import FirebaseMessaging
import UserNotifications
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    var firebaseToken : String = "";
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    Messaging.messaging().delegate = self;
    FirebaseApp.configure()
    GeneratedPluginRegistrant.register(with: self)
    Messaging.messaging().isAutoInitEnabled = true;
    self.registerForFirebaseNotification(application: application);
    return true;
   // GeneratedPluginRegistrant.register(with: self)
    
  }
   override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken : Data){
    print("X__APNS: \(String(describing: deviceToken))")
       Messaging.messaging().apnsToken = deviceToken;
    //Messaging.messaging().setAPNSToken(deviceToken, type:MessagingAPNSTokenType.prod )
    }
    
    override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("X_ERR",error);
    }
    
     func registerForFirebaseNotification(application : UIApplication){
    //    Messaging.messaging().delegate     = self;
        if #available(iOS 10.0, *) {
            //UNUserNotificationCenter.current().delegate = self ;
            let authOpt : UNAuthorizationOptions = [.alert, .badge, .sound];
            UNUserNotificationCenter.current().requestAuthorization(options: authOpt, completionHandler: {_, _ in})
            UNUserNotificationCenter.current().delegate = self ;
        }else{
            let settings : UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)                
            application.registerUserNotificationSettings(settings);
        }
        application.registerForRemoteNotifications();
    }
}

extension AppDelegate : MessagingDelegate{
    func messaging(_messagin : Messaging, didRecieveRegistrationToken fcmToken : String){
        self.firebaseToken = fcmToken;
        print("X__FCM: \(String(describing: fcmToken))")
    }
    func messaging(_messagin : Messaging, didRecieve remoteMessage : Any){
        //self.firebaseToken = fcmToken;
        print("REMOTE__MSG: \(remoteMessage)")
    }
    func application(_ application : UIApplication,didRecieveRemoteNotification uinfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void){
        print("WITH__APN: \(uinfo)")
    }
}

podfile

target 'Runner' do
  use_frameworks!
  use_modular_headers!

#  pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => '7.11.0'

  pod 'Firebase/Auth'
  pod 'Firebase/Analytics'
  pod 'FBSDKLoginKit'
  pod 'Firebase/Messaging'

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

pubspec.yaml

  cloud_firestore: ^2.0.0
  firebase_auth: ^1.1.2
  firebase_core: ^1.1.0
  firebase_messaging: ^9.1.3
  flutter_local_notifications: ^5.0.0+3

Answered here also

Upvotes: 2

George Hoss
George Hoss

Reputation: 171

I had the same problem, I went step by step again with firebase documentation and realize that the push notification capability was missing on debug and release modes.

Steps to solve the issue:

  1. Go to xcode
  2. Select runner
  3. Signing & Capabilities
  4. Check debug and release capabilities you need to have background modes and push notification

push notification capability

https://firebase.flutter.dev/docs/messaging/apple-integration

Upvotes: 13

Related Questions