``` // MyProjApp.swift // MyProj // // Created by Karrsen Bryant on 9/20/21. // import SwiftUI import Firebase @main struct MyProj: App {       init(){     FirebaseApp.configure()   }       @StateObject var userInfo = UsersInfo()       var body: some Scene {     WindowGroup {       ContentView().environmentObject(userInfo)     }   } } struct MyProj_Previews: PreviewProvider {   static var previews: some View {     LoginView()   } } ``` ``` // ContentView.swift // MyProj // // Created by Karrsen Bryant on 3/24/22. // import SwiftUI struct ContentView: View {   @EnvironmentObject var userInfo: UsersInfo       var body: some View {     Group {       if userInfo.isUserAuthenticated == .undefined{           Text("Loading")       } else if userInfo.isUserAuthenticated == .signedOut{           LoginView()       } else {         MainView()       }     }.onAppear {       self.userInfo.configureFirebaseStateDidChange()     }         } } ``` ``` // // MainView.swift // MyProj // // Created by Karrsen Bryant on 3/24/22. // import Foundation import SwiftUI struct MainView: View{   @EnvironmentObject var loggedInUser: UsersInfo   var testData = TestingTruthSource.testData   var body: some View{     TabView{       NavigationView{         var stateManager = HomeFeedModel(eo: loggedInUser)         HomeFeedView(stateManager: stateManager, testData: testData)           .hiddenNavigationBarStyle()       }       .tabItem { Image(systemName: "house.fill") }                       NavigationView{         FullScreenMapView()           .hiddenNavigationBarStyle()       }       .tabItem { Image(systemName: "globe") }                       NavigationView{         let someVM = SearchViewManager(loggedInUser: loggedInUser.user)         SearchView(searchViewManager: someVM)           .navigationBarTitleDisplayMode(.inline)           .navigationBarHidden(true)       }       .tabItem { Image(systemName: "magnifyingglass") }                       NavigationView{                   GroupView()           .navigationBarTitleDisplayMode(.inline)           .navigationBarHidden(true)       }       .tabItem { Image(systemName: "person.3.fill") }                       NavigationView{         ProfileView(loggedInUserObject: loggedInUser.user)           .navigationBarTitleDisplayMode(.inline)           .navigationBarHidden(true)       }       .tabItem { Image(systemName: "person.fill") }                     }   } } struct MainView_Previews: PreviewProvider{   static var userInfo = UsersInfo()   static var previews: some View{     MainView().environmentObject(userInfo)   } } ``` ``` // // UserInfo.swift //  // // Created by Karrsen Bryant on 2/10/22. // import Foundation import FirebaseAuth @MainActor class UsersInfo: ObservableObject {   enum AuthState{     case undefined, signedOut, signedIn   }       @Published var isUserAuthenticated: AuthState = .undefined   @Published var user: FBUser = .init(id: "", name: "", email: "", bio: "", friendsIds: [], relationships: [:], eventsIds: [], groupsIds: [])       var authStateDidChangeListenerHandle: AuthStateDidChangeListenerHandle?       func configureFirebaseStateDidChange(){     print("authStateDidChangeListenerHandle being recalled")     authStateDidChangeListenerHandle = Auth.auth().addStateDidChangeListener({ (Auth, user) in       guard let user = user else {         print("currently signed out")         self.user = FBUser()         self.isUserAuthenticated = .signedOut         return       }       self.isUserAuthenticated = .signedIn       print("user will be: \(user.uid)")       print("signed in... according to state")       FBFireStoreFunctions.retrieveFBUser(uid: user.uid) { (result) in         print("Retrieved the result of retrieveFBUser")         switch result {         case .failure(let error):           print("still no user here")           print(error.localizedDescription)         case .success(let user):           self.user = user           print("name: \(self.user.name)")                     }       }     })   } } ``` ``` //FBFirestore Functions import FirebaseFirestore import FirebaseCore import SwiftUI enum FBFireStoreFunctions{       //Setters   static func retrieveFBUser(uid: String, completion: @escaping (Result<FBUser, Error>)->()) {     print("retrieving a user for the string: \(uid)")     //Later we will assign FBRelationship objects to this placeholder     //and that array will be assigned to the FBUser object     var relationships: [String : String] = [:]     //Make a Firestore object to access the database     let firestore = Firestore.firestore()     //assign the collection that we're going to search and then query     let relationshipsReference = firestore.collection(FBKeys.CollectionPath.Relationships)     //FS.doc(uid) is the document that holds the user's relationships when their     //UserId of the two users, getFBDocument obviously retrieves the object or sends an error along.     let userReference = firestore       .collection(FBKeys.CollectionPath.FBUsers)       .document(uid)           getFBDocument(for: relationshipsReference.document(uid)) { (result) in       switch result{       case .success(let data):         for key in data.keys {           let value = data[key] as? String ?? ""           relationships[key] = value         }       case .failure(let error):         print("no document")       }       relationshipsReference         .whereField(uid, isGreaterThan: "")         .getDocuments { (snapshot, error) in           if let err = error {             print("some error getting snapshot \(err.localizedDescription)")           }           guard let snap = snapshot else {             print("no error but no snapshot")             return           }           //Snapshot exists           for d in snap.documents {             //Accessing individual fields             for key in d.data().keys {               //Only care about relationships with this user               if key == uid {                 //Cast the value, it is a string                 let value = d.data()[key] as? String ?? ""                 //Make a relationship object and add it to the array                 relationships[d.documentID] = value               }             }           }           getFBDocument(for: userReference) { (result) in             switch result {             case .success(var data):               print("\(relationships)")               data["relationships"] = relationships               guard let user = FBUser(documentData: data) else {                 completion(.failure(FireStoreError.noUser))                 return               }               completion(.success(user))             case .failure(let err):               completion(.failure(err))             }           }         }     }   } } ```