I’m trying to learn how to do basic login in swift with Firebase and it’s causing me to lose my mind over navigating to the main page of the app once the login is complete. I have a ViewModel
that manages the login, and in the view I have added an onReceive
property to listen on a viewModel’s boolean to detect sign in and trigger the navigation. I don’t understand why it’s not working, any help would be greatly appreciated!
ViewModel:
class LoginViewModel: ObservableObject {
let auth = Auth.auth()
var userInfo: User?
@Published var isSignedIn = false
func signIn(email: String, password: String) {
auth.signIn(withEmail: email, password: password) { _, error in
if let error = error as? NSError {
print("Error happened on login"+error.description)
} else {
print("Login successful")
if let user = self.auth.currentUser {
print("We have a user")
self.userInfo = user
self.isSignedIn.toggle()
}
}
}
}
}
View:
struct LoginPage: View {
@State var email = ""
@State var password = ""
@ObservedObject var viewModel = LoginViewModel()
var body: some View {
NavigationView {
ZStack {
VStack {
TextField("Email", text: $email).padding()
.background(Color(.secondarySystemBackground))
.padding()
TextField("Password", text: $password).padding()
.background(Color(.secondarySystemBackground))
.padding()
Button(action: {
guard !email.isEmpty, !password.isEmpty else {
return
}
viewModel.signIn(email: email, password: password)
}, label: {
Text("Sign in")
.padding(EdgeInsets(top: 12, leading: 35, bottom: 12, trailing: 35))
.foregroundColor(.white)
.background(Color.blue)
.cornerRadius(15)
})
}
}.navigationTitle("Login")
}.onReceive(viewModel.$isSignedIn) { isSignedIn in
if isSignedIn {
print("ok damm")
NavigationLink(destination: HomePage()) {
EmptyView()
}
}
}
}
}
Note that "ok damm" prints every time.
3
Answers
Answer by Jatin Bhuva works but is deprecated for iOS 16. Here's the solution for new iOS versions:
Notice how I replaced the
NavigationView
with aNavigationStack
and added.navigationDestination(isPresented:)
that listens for changes on my model'sisSignedIn
published property.Try the below code it will help you to solve your issue:
View:
switch statement in swiftui can handle that easily. I use it all the time;
And your view should look like this;