Combine: Wrapped async call with Future, but Future.sink doesn't appear to complete

Viewed 328

First-time poster, long-time reader ... I've wrapped an async call to the Firebase Authorization API. I'm calling it from inside a SwiftUI View function.

func authenticateFirebaseEmail(email: String, password: String) -> 
    Future<String, Error> {
        return Future<String,Error> {  promise in
                Auth.auth().signIn(withEmail: email, password: password) { result, error in
            if let error=error {
                print("failure detected")
                promise(.failure(error))
            }
            
            if let result=result {
                print("result detected - returning success promise")
                promise(.success(result.user.email!))
            }
            
        }
    }
}
...

func logMeInFuncInView() {
        var cancellable : AnyCancellable?
        cancellable = authenticateFirebaseEmail(email: self.userEmail, password: self.password).map( {
            value in return value
        })
        .sink(receiveCompletion: { (completion) in
            print("completion received")
        }, receiveValue: { user in
            print("value received")
            self.errorMessage = user
            })
    }

The console output is as follows, but never reaches the "completion received" or "value received" calls: result detected - returning successful promise

Is the issue with the wrapped callback, the future, the way I'm using the future, or something that I'm not seeing entirely?

1 Answers

Your cancellable is local variable, so destroyed once went off context. As soon as subscriber is destroyed it cancels subscription and, as it is only one, publisher cancelled as well.

Your solution is to make your cancellable as property, ie

var cancellable : AnyCancellable?  // << here !!

func logMeInFuncInView() {
        cancellable = authenticateFirebaseEmail(email: self.userEmail, password: self.password).map( {
            value in return value
        })
        // .. other code
}
Related