So my goal is to fix this condition issue when it comes to instantiating the right viewController. I have a function that I basically use to navigate a user to the right viewController depending on the type of user and if they're logged in or not.
Here is this function :
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
self.window = window
let auth = Auth.auth()
let actualuser = Auth.auth().currentUser
auth.addStateDidChangeListener { (_, user) in
if user != nil {
db.document("student_users/\(actualuser?.uid)").getDocument { (docSnapshot, error) in
if error != nil {
print("\(error)")
} else {
let docSnap = docSnapshot?.exists
guard docSnap! else {
let alreadyLoggedInAsASchoolViewController = self.storyboard.instantiateViewController(withIdentifier: Constants.StoryboardIDs.SchoolEventDashboardStoryboardID) as! SchoolTableViewController
let navigationizedSchoolVC = UINavigationController(rootViewController: alreadyLoggedInAsASchoolViewController)
self.window!.rootViewController = navigationizedSchoolVC
self.window!.makeKeyAndVisible()
return
}
let alreadyLoggedInAsAStudentViewController = self.storyboard.instantiateViewController(withIdentifier: Constants.StoryboardIDs.StudentEventDashboardStoryboardID) as! StudentSegmentedTableViewController
let navigationizedVC = UINavigationController(rootViewController: alreadyLoggedInAsAStudentViewController)
self.window!.rootViewController = navigationizedVC
self.window!.makeKeyAndVisible()
}
}
} else {
let notLoggedInAtAll = self.storyboard.instantiateViewController(withIdentifier: Constants.StoryboardIDs.GothereMainMenuStoryboardID) as! GothereMainMenuViewController
let navMainMenu = UINavigationController(rootViewController: notLoggedInAtAll)
self.window!.rootViewController = navMainMenu
self.window!.makeKeyAndVisible()
}
}
}
I also have the exact block of code like this for the sceneDidEnterForeground
for push notification purposes. Now the issue is when I run the simulator and launch the app for the first time, the correct viewController will show up, but when I logout as a school user and login as a school user in that same simulator session, the wrong viewController (aka the viewController of the other type of user) shows up.
Not that it would be a real situation in production where a student user would just have access to a school user's account and log in like that in the same scene session, but still, better to be safe than sorry. So this leads to me ask, is this a memory leak or a completely different issue?
I also get this error :
Your query is based on the variable actualuser
, which looks like it is only set once, when the scene is first set up. Inside the state change callback, it's never updated.
So, when you log out, then log back in as a different user, that initial value of actualuser
will be used, explaining why you see the wrong view controller. Then, when you run the app again and the scene is set up, actualuser
gets set to the auth().currentUser again, showing you the correct view controller.
The solution here is to base your query on the current (and current) user.
Something like:
db.document("student_users/\(user.uid)")
(Instead of checking user != nil
, do an optional binding with let user = user
and then you can avoid the ?
unwrapping)
This is not, by the way, a memory leak, which is a different type of issue: https://en.wikipedia.org/wiki/Memory_leak