Reputation: 3046
I have an app using FirebaseAuth to authenticate users. I do this in an AuthService class;
import Foundation
import FirebaseAuth
class AuthService: NSObject {
private override init() {}
static let shared = AuthService()
let currentUser = Auth.auth().currentUser
var uid = Auth.auth().currentUser?.uid
func checkAuthState(completion: @escaping(FirebaseAuth.User?) -> Void) {
// let listener = Auth.auth().addStateDidChangeListener { (auth, user) in
Auth.auth().addStateDidChangeListener { (auth, user) in
switch user {
case .none:
print("USER NOT FOUND IN CHECK AUTH STATE")
completion(nil)
case .some(let user):
print("USER FOUND WITH ID: \(user.uid)")
completion(user)
}
}
// Auth.auth().removeStateDidChangeListener(listener)
}
}
I then sign in a user anonymously using checkAuthState function above. Once this operation completes with some user I perform an action to switch the rootViewController
.
func checkAuthState() {
authService.checkAuthState { (user) in
switch user {
case .none:
SceneDelegate.shared.rootController.showWelcomeController()
case .some(_):
SceneDelegate.shared.rootController.showTabBarController()
}
}
}
}
Here is my code within my RootViewController
;
func showWelcomeController() {
let welcomeController = WelcomeController(authService: AuthService.shared)
let navigationController = UINavigationController(rootViewController: welcomeController)
addChild(navigationController)
navigationController.view.frame = view.frame
view.addSubview(navigationController.view)
navigationController.didMove(toParent: self)
currentController.willMove(toParent: nil)
currentController.view.removeFromSuperview()
currentController.removeFromParent()
currentController = navigationController
}
func showTabBarController() {
let tabBarController = TabBarController()
addChild(tabBarController)
tabBarController.view.frame = view.frame
view.addSubview(tabBarController.view)
tabBarController.didMove(toParent: self)
currentController.willMove(toParent: nil)
currentController.view.removeFromSuperview()
currentController.removeFromParent()
currentController = tabBarController
}
The above operates all as expected and shows my TabBarController
, however, I then run a function in one of my ViewControllers in my TabBarController which is;
var uid = Auth.auth().currentUser?.uid
func readComments(query: Query, lastDocument: DocumentSnapshot?, completion: @escaping(Result<[CommentModel], NetworkError>) -> ()) {
guard let uid = auth.uid else { return completion(.failure(.userNotFound)) }
// Other code
}
However, I get the .userNotFound error? as it returns nil? I'm confused as checkAuthState is returning a user?
Upvotes: 0
Views: 455
Reputation: 598728
This typically means that the currentUser
is not yet initialized by the time that code runs. Since restoring the user's sign-in state requires a call to the server, it is an asynchronous operation.
Any code that depends on the current user state being restored should be inside (or be called from) an addStateDidChangeListener
as in your first snippet. So you may need a snippet like that in your other view controller(s) too.
Upvotes: 1