Search code examples
swiftfirebasefirebase-authenticationalamofire

Adding Firebase IdToken with Completion Handler to Every AlamoFire Request


I understand how to add customer HTTP Requests headers, such as Authorization Tokens, like this SO Question

My complication is around using the Firebase API to get the bearer token because it has a completion handler in the event the bearer token has expired, the refresh token is used to try and get a fresh bearer token:

static func getIdToken(completion: @escaping (String?, Error?) -> Swift.Void) {
    guard let user =  Auth.auth().currentUser else {
        print("No Firebase User!")
        completion(nil, nil)
        return
    }

    user.getIDToken { (idToken, error) in
        if(error != nil ) {
            print("AuthUtiltiy, error retrieving token: \(error!.localizedDescription)")
            completion(nil, error)
            return
        }

        completion(idToken, nil);
    }
}

I have started to abstract around the AlamoFire SessionManager where I can add additional HTTP Request Headers: class LibraryAPI: NSObject {

private var manager = Alamofire.SessionManager.default

// Setups the cookie and shared instance
override init() {
    let defaultHeaders = manager.session.configuration.httpAdditionalHeaders ?? [:]
    let configuration = URLSessionConfiguration.default
    configuration.httpAdditionalHeaders = defaultHeaders
    manager = Alamofire.SessionManager(configuration: configuration)
}

But because of this callback/completion handler in the Firebase getIdToken call, I cannot do achieve adding an auth token to every request in the my abstraction init.

I also tried to wrap up my actual HTTP requests using AlamoFire but I still have the same issue.

I do not think I can use a RequestAdapter, introduced in AlamoFire 4.0, again because of the same Firebase.getIdToken Callback/Completion handler.


Solution

  • There's no easy way to support this in Alamofire 4 due to RequestAdapter being synchronous, as you noted. However, in Alamofire 5 (currently in beta) RequestAdapter was updated to be asynchronous for exactly the reason posted here. Updating, if you can, would be the easiest way to elegantly support this case.