iosfirebaseswift3instanceid

iOS Swift Firebase InstanceID token returns Nil at first time


I am using Firebase notification in my app. When I install my app for first time FIRInstanceID.instanceID().token() returns nil, but it won't return nil at next time. Everything is done perfect except this.

Here is the code:

import UIKit
import Firebase
import FirebaseMessaging
import FirebaseInstanceID
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, FIRMessagingDelegate
{

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
        //Configuring Firebase
        FIRApp.configure()
if #available(iOS 10.0, *)
        {
            print("Test")
            // For iOS 10 display notification (sent via APNS)
            UNUserNotificationCenter.current().delegate = self
            UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .sound, .alert]) { (granted, error) in
                if granted
                {
                    //self.registerCategory()
                }
            }
            // For iOS 10 data message (sent via FCM)
            FIRMessaging.messaging().remoteMessageDelegate = self
        }
        else
        {
            let settings: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()
NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotification), name: NSNotification.Name.firInstanceIDTokenRefresh, object: nil)
        return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
    {
        FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.sandbox)
        FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.prod)
    }
func tokenRefreshNotification(notification: NSNotification)
    {
        if let refreshedToken = FIRInstanceID.instanceID().token()
        {
            print("InstanceID token: \(refreshedToken)")
        }
        // Connect to FCM since connection may have failed when attempted before having a token.
        connectToFcm()
    }

    func connectToFcm()
    {
        FIRMessaging.messaging().connect { (error) in
            if (error != nil)
            {
                print("Unable to connect with FCM. \(error)")
            }
            else
            {
                print("Connected to FCM.")
            }
        }
    }
}

In Remote Page I am Calling Firebase InstanceID Token

let token = FIRInstanceID.instanceID().token()

But at first time it return nil value.


Solution

  • change the order of FIRApp.configure() and try once, for more information you can get the sample here

    func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
    // Register for remote notifications. This shows a permission dialog on first run, to
    // show the dialog at a more appropriate time move this registration accordingly.
    // [START register_for_notifications]
    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 })
    
      // For iOS 10 data message (sent via FCM)
      FIRMessaging.messaging().remoteMessageDelegate = self
    
    } else {
      let settings: UIUserNotificationSettings =
      UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
      application.registerUserNotificationSettings(settings)
    }
    
    application.registerForRemoteNotifications()
    
    // [END register_for_notifications]
    FIRApp.configure()
    
    // [START add_token_refresh_observer]
    // Add observer for InstanceID token refresh callback.
    NotificationCenter.default.addObserver(self,
        selector: #selector(self.tokenRefreshNotification),
        name: .firInstanceIDTokenRefresh,
        object: nil)
    // [END add_token_refresh_observer]
    return true
    }
    

    on that delegate check once the token is comes or not

    func tokenRefreshNotification(notification: NSNotification) {
          //  print("refresh token call")
            guard let contents = FIRInstanceID.instanceID().token()
            else {
                return
            }
               // let refreshedToken = FIRInstanceID.instanceID().token()!
                print("InstanceID token: \(contents)")
    
               // UserDefaults.standardUserDefaults().set(contents, forKey: "deviceToken");
                // Connect to FCM since connection may have failed when attempted before having a token.
    
                connectToFcm()
    
        }
    

    finally connect the FCM like

    func connectToFcm() {
    // Won't connect since there is no token
    guard FIRInstanceID.instanceID().token() != nil else {
      return
    }
    
    // Disconnect previous FCM connection if it exists.
    FIRMessaging.messaging().disconnect()
    
    FIRMessaging.messaging().connect { (error) in
      if error != nil {
        print("Unable to connect with FCM. \(error?.localizedDescription ?? "")")
      } else {
        print("Connected to FCM.")
      }
    }
      }