Im trying to set up firebase authentication in my app. I have a SessionStore class which is an Observable object which manages the auth state and provides a sign up and sign in function.
I am trying to update the session in the sign up function instead of in the listen function however this is causing the value to be null when I try and get it in my UserView. However, if I set it in the listen function its getting the values perfectly fine.
I need to set it in the Sign Up function as I need access to the username and email that are passed into that function.
Let me know if you need to see other screens.
SessionStore.Swift
//
// SessionStore.swift
// Crep Collect
//
// Created by Rex on 12/04/2021.
//
import SwiftUI
import Firebase
import Combine
class SessionStore : ObservableObject {
var didChange = PassthroughSubject<SessionStore, Never>()
@Published var session: User? { didSet { self.didChange.send(self) }}
var handle: AuthStateDidChangeListenerHandle?
@Published var isLoggedIn = false
private var profileRepository = UserProfileRepository()
func listen () {
// monitor authentication changes using firebase
handle = Auth.auth().addStateDidChangeListener { (auth, user) in
if let user = user {
self.isLoggedIn = true
print("Got user: \(user)")
//returns the value correctly when setting it in here
// self.session = User(
// uid: user.uid,
// username: "hrfew",
// email: "heb@me.com"
// )
} else {
self.isLoggedIn = false
// if we don't have a user, set our session to nil
// self.session = nil
print("no user")
}
}
}
func signUp(email: String, password: String, username: String, completion: @escaping (_ profile: User?, _ error: Error?) -> Void) {
Auth.auth().createUser(withEmail: email, password: password) { (result, error) in
if let error = error {
print("Error signing up: \(error)")
completion(nil, error)
return
}
guard let user = result?.user else { return }
print("User \(user.uid) signed up.")
let userProfile = User(uid: user.uid, username: username, email: email)
self.profileRepository.createProfile(profile: userProfile) { (profile, error) in
if let error = error {
print("Error while fetching the user profile: \(error)")
completion(nil, error)
return
}
// returns nil when setting it here
self.session = User(uid: user.uid, username: username, email: email) //set session here not working
// print(self.session)
completion(profile, nil)
}
}
}
func signIn(
email: String,
password: String,
handler: @escaping AuthDataResultCallback
) {
Auth.auth().signIn(withEmail: email, password: password, completion: handler)
}
func signOut () -> Bool {
do {
try Auth.auth().signOut()
self.session = nil
return true
} catch {
return false
}
}
func unbind () {
if let handle = handle {
Auth.auth().removeStateDidChangeListener(handle)
}
}
}