I'm building an app that uses firebase to authenticate users. I'm trying to sign up a new user and keep getting a fatal error. New to Swift so I'm probably missing something obvious.
Error: Fatal error: No ObservableObject of type AuthViewModel found. A View.environmentObject(_:) for AuthViewModel may be missing as an ancestor of this view. This is focused on my sign up action button where the viewModel is referenced (see just below // end of v).
Sign Up View code:
import SwiftUI
struct SignUpView: View {
@State var firstName = ""
@State var lastName = ""
@State var email = ""
@State var password = ""
@State var confirmPassword = ""
@Environment(\.presentationMode) var mode
@EnvironmentObject var viewModel: AuthViewModel
var body: some View {
ZStack {
BackgroundGradientView()
VStack {
LogoView()
.padding(.bottom, 25)
VStack(spacing:20) {
UserTextField(text: $firstName, placeholder: "First Name")
UserTextField(text: $lastName, placeholder: "Last Name")
EmailTextField(text: $email)
PasswordSecureField(text: $password, placeholder: "Password")
PasswordSecureField(text: $confirmPassword, placeholder: "Confirm Password")
} // end of V
.padding(.horizontal, 32)
Button { // sign up action
viewModel.register(withEmail: email, password: password, firstName: firstName, lastName: lastName)
} label: {
AuthenticateButtonView(text: "Sign Up").padding()
}
Spacer()
Button {
mode.wrappedValue.dismiss()
} label: {
HStack {
Text("Already have an account?")
.font(.system(size:14))
Text("Sign In")
.font(.system(size:14, weight:.semibold))
}
.foregroundColor(.white)
}
.padding(.bottom,16)
} // end of second V
}
}
}
struct SignUpView_Previews: PreviewProvider {
static var previews: some View {
SignUpView()
}
}
AuthViewModel code:
import SwiftUI
import Firebase
import FirebaseAuth
class AuthViewModel: ObservableObject {
@Published var userSession: User?
@Published var currentUser: AppUser?
static let shared = AuthViewModel()
init() {
userSession = Auth.auth().currentUser
//fetchUser()
}
func fetchUser() {
guard let uid = userSession?.uid else { return }
COLLECTION_USERS.document(uid).getDocument {
snapshot, _ in
guard let user = try? snapshot?.data(as: AppUser.self) else { return }
self.currentUser = user
}
}
func login(withEmail email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { result, error in
if let error = error {
print("Login Failed\(error.localizedDescription)")
return
}
guard let user = result?.user else { return }
self.userSession = user
self.fetchUser()
}
}
func register(withEmail email: String, password: String, firstName: String, lastName: String) {
Auth.auth().createUser(withEmail: email, password: password) {
result, error in
if let error = error {
print("Registeration Failed \(error.localizedDescription)")
return
}
guard let user = result?.user else { return }
let data = ["uid": user.uid,
"firstName": firstName,
"lastName": lastName,
"email": email]
COLLECTION_USERS.document(user.uid).setData(data) { _ in
print("Succesfully uploaded data")
self.userSession = user
self.fetchUser()
}
}
}
func signout() {
self.userSession = nil
try? Auth.auth().signOut()
}
}
Again, probably something obvious but would benefit from an explainer.