This is what I am doing:
-> Login/Signup to Firebase using FirebaseAuthentification
-> Listining to AuthStateDidChangeListenerHandle
-> I store extra user information in Firestore, therefore I check if the user exists in Firestore
-> If the user does not exist I create an empty user
-> If everything was successful I return a Future Publisher via callback (I want to change that as well)
This is the checkLoginState function:
func checkLoginState(completion: @escaping (AnyPublisher<AccountDetails,Error>) -> Void) {
self.handler = Auth.auth().addStateDidChangeListener { [weak self] auth, user in
guard let safeSelf = self else { return }
completion(Future<AccountDetails,Error> { promise in
if let user = user {
print(user)
print(auth)
safeSelf.checkIfUserIsInDatabase(user: user.uid) { result in
switch result {
case .success(let isAvailable):
if isAvailable {
promise(.success(AccountDetails(userUID: user.uid,name: user.displayName, loggedIn: true, premiumUser: false)))
} else {
safeSelf.createEmptyUser(user: user.uid,email: user.email) { result in
switch result {
case .success(_):
promise(.success(AccountDetails(userUID: user.uid,name: user.displayName, loggedIn: true, premiumUser: false)))
case .failure(let error):
print(error)
}
}
}
case .failure(let error):
print(error)
}
}
} else {
promise(.success(AccountDetails(userUID: nil, loggedIn: false, premiumUser: false)))
}
}.eraseToAnyPublisher()
)
}
}
These are my current functions:
private func checkIfUserIsInDatabase(user id: String, completion: @escaping (Result<Bool,Error>) -> Void)
private func createEmptyUser(user id: String, email:String?, completion: @escaping (Result<Bool,Error>) -> Void)
Thats what I want to use:
private func checkIfUserIsInDatabase(user id: String) -> AnyPublisher<Bool,Error>
private func createEmptyUser(user id: String) -> AnyPublisher<Bool,Error>
func checkLoginState() -> AnyPublisher<AccountDetails,Error>
I had something like that, but it does not work, also looks confusing:
func checkLoginState(completion: @escaping (AnyPublisher<AccountDetails,Error>) -> Void) {
self.handler = Auth.auth().addStateDidChangeListener { [weak self] auth, user in
guard let safeSelf = self else { return }
completion(Future<AccountDetails,Error> { promise in
if let user = user {
print(user)
print(auth)
safeSelf.checkIfUserIsInDatabase(user: user.uid)
.sinkToResult { value in
switch value {
case .success(let isUserInDatabase):
if isUserInDatabase {
promise(.success(AccountDetails(userUID: user.uid,name: user.displayName, loggedIn: true, premiumUser: false)))
} else {
safeSelf.createEmptyUser(user: user.uid)
.sinkToResult { value in
switch value {
case .success( _):
promise(.success(AccountDetails(userUID: user.uid,name: user.displayName, loggedIn: true, premiumUser: false)))
case .failure(let error):
print(error)
}
}
}
case .failure(let error):
print(error)
}
}
} else {
promise(.success(AccountDetails(userUID: nil, loggedIn: false, premiumUser: false)))
}
}.eraseToAnyPublisher()
)
}
}