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

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?

If you chain the .print() operator onto your future before .sink, you should see that the future is being cancelled before the value/completion is ever received. The returned AnyCancellable needs to be retained somewhere for the lifetime of the future. Because it's local to logMeInFuncInView(), it's being cancelled the moment the function returns.

1 Like

Thank you! Yeah, I see it now. Guess I gotta figure out how to get that AnyCancellable into a mutable variable.

Terms of Service

Privacy Policy

Cookie Policy