Q:

Error when launching app with firebase cloud messaging

I am trying to integrate firebase cloud messaging into my app inorder to send notifications to users. When trying to start up the app, I am getting the following error:
    *** First throw call stack:
(0x1e024927c 0x1df4239f8 0x1e01534b0 0x102a31268 0x102995540 0x1029956f8 0x20cb84088 0x20cb83944 0x102995878 0x1dfc9a8e0)
libc++abi.dylib: terminating with uncaught exception of type NSException

This happens here:
    [NSException raise:NSInternalInconsistencyException

in FIRAuth.m.
  [NSException raise:NSInternalInconsistencyException
                format:@"The default FIRApp instance must be configured before the default FIRAuth"
                       @"instance can be initialized. One way to ensure that is to call "
                       @"`[FIRApp configure];` (`FirebaseApp.configure()` in Swift) in the App "
                       @"Delegate's `application:didFinishLaunchingWithOptions:` "
                       @"(`application(_:didFinishLaunchingWithOptions:)` in Swift)."];

This is what most of my app delegate looks like:
      let currentUser = Auth.auth().currentUser!.uid

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        FirebaseApp.configure()
        Messaging.messaging().delegate = self as! MessagingDelegate

//        InstanceID.instanceID().instanceID { (result, error) in
//            if let error = error {
//                print("Error fetching remote instange ID: \(error)")
//            } else if let result = result {
//                print("Remote instance ID token: \(result.token)")
//                let ref = Database.database().reference()
//                ref.child("UsersFireTokens").child(self.currentUser).child("token").setValue(result.token)
//            }
//        }

        return true
    }

    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        if #available(iOS 10.0, *) {//for notif's
            // For iOS 10 display notification (sent via APNS)
            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 true
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
        InstanceID.instanceID().instanceID { (result, error) in
            if error == nil {
                print("InstanceID token: \(result)")
//                let ref = Database.database().reference()
//                ref.child("UsersFireTokens").child(self.currentUser).child("token").setValue(result!)
            } else {
                print(error, ": Error in getting token for Fire")
            }
        }
//        if let refreshedToken = InstanceID.instanceID().token() {
//            print("InstanceID token: \(refreshedToken)")
//        }
    }

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        print("Firebase registration token: \(fcmToken)")

        let dataDict:[String: String] = ["token": fcmToken]
        NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
        // TODO: If necessary send token to application server.
        let ref = Database.database().reference()
        ref.child("UsersFireTokens").child(self.currentUser).child("token").setValue(dataDict["token"]!)
        // Note: This callback is fired at each app startup and whenever a new token is generated.
    }

    // MARK: - MessagingDelegate

    func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
        print(fcmToken, ": fcmToken")
        let ref = Database.database().reference()
        ref.child("UsersFireTokens").child(self.currentUser).child("token").setValue(fcmToken)

    }

What is happening and how can i fix this error?
I was trying to follow the instructions here...

A:

You can't have this line 
let currentUser = Auth.auth().currentUser!.uid

outside a function - It will be called when the App Delegate is initialised, which is before didFinishLaunching is called - This means that Auth.auth() is being initialised before calling FireBaseApp.configure() as the exception said.
I would suggest:
var currentUser: String?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    FirebaseApp.configure()
    Messaging.messaging().delegate = self as! MessagingDelegate

    self.currentUser = Auth.auth().currentUser?.uid

    return true
}

