Yes, there is a better way. But first: you have a logic error. The Future initializer runs its argument immediately. But an Effect should not do anything until you subscribe to its publisher! You need to wrap the Future in a Deferred publisher so that the closure doesn't get called until there's a subscriber.
Also, you don't need to use eraseToAnyPublisher before eraseToEffect, because eraseToEffect is a Publisher extension so you can use it directly on Deferred or (unfortunately, in this case) Future.
Anyway, here's the better way: Effect has a static future method that applies Deferred, Future, and eraseToEffect for you. Something like this should work:
func register(email: String, password: String) -> Effect<User, RegisterApiError> {
return .future { promise in
Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
if let error = error {
promise(.failure(RegisterApiError(errorName: error.localizedDescription)))
}
else if let name = authResult?.user.displayName, let email = authResult?.user.email {
let user = User(name: name,
email: email)
promise(.success(user))
}
}
}
}