I'm using Firebase and SwiftUI to log in as a user. I have everything working but can't figure out how to navigate to the next page once the user is successfully logged in. NavigationLinks seem weird to me so I'm wondering if there's any other way to navigate to the next view. The LoginView contains the login screen and the LoginViewModel does the sign-in procedure with Firebase. The issue is that if I return views based on a variable in the root view, it doesn't change the view once any view other than the root view is opened (i.e if I navigate to the Login view, it won't go to the main view after the login button is pressed).
ContentView (The root view displaying all the other views):
import SwiftUI
struct ContentView: View {
@StateObject var userLoggedIn = LoginViewModel()
var body: some View {
if !userLoggedIn.isLoggedIn {
LoginView()
}
else {
MainView()
}
}
}
LoginView:
import SwiftUI
import FirebaseAuth
struct LoginView: View {
@State private var email: String = ""
@State private var password: String = ""
@State private var isEditing = false
@State private var showPassword = false
@State private var radius = 300
private var canLogIn: Bool {
return !email.isEmpty && !password.isEmpty
}
let loginView = LoginViewModel()
@ViewBuilder
var body: some View {
return NavigationView(content: {
VStack {
Spacer()
.frame(height: 150)
Text("PET SUPPORT").foregroundColor(Color.petSupportText)
.font(Font.custom("Permanent Marker", size: 36))
.padding()
Group {
HStack {
Text("EMAIL")
.font(Font.custom("Permanent Marker", size: 18))
.padding(.top, 10)
Spacer()
}
TextField("Email", text: $email) {
isEditing in self.isEditing = isEditing
}
.autocapitalization(.none)
.keyboardType(.emailAddress)
.disableAutocorrection(true)
.padding(.top, 20)
Divider()
.foregroundColor(.black)
}
Group {
HStack {
Text("PASSWORD")
.font(Font.custom("Permanent Marker", size: 18))
.padding(.top, 10)
Spacer()
}
ZStack {
if showPassword {
TextField("Password", text: $password)
}
else {
SecureField("Password", text: $password)
}
}
.frame(height: 20)
.autocapitalization(.none)
.overlay(Image(systemName: showPassword ? "eye.slash" : "eye").onTapGesture { showPassword.toggle() }, alignment: .trailing)
.disableAutocorrection(true)
.padding(.top, 20)
Divider()
.foregroundColor(.black)
}
Spacer();
Group {
Button(action: {
loginView.login(email: email, password: password)
radius = 2000
MainView()
}, label: {
Text("Login")
})
.foregroundColor(.white)
.font(Font.custom("Permanent Marker", size: 18.0))
.padding(.horizontal, 20)
.padding()
.background(Color.petSupportBlue)
.cornerRadius(70.0)
.disabled(!canLogIn)
}
Spacer()
}
.padding(.horizontal, 30)
.ignoresSafeArea()
})
}
}
LoginViewModel:
import Foundation
import Firebase
class LoginViewModel: ObservableObject {
@Published var isLoggedIn = false
func login(email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { (result, error) in
if let error = error {
print(error.localizedDescription)
} else {
print("Logged In!")
self.isLoggedIn = true
}
}
}
}
MainView:
import SwiftUI
struct MainView: View {
var body: some View {
Text("Hello, World!")
}
}