// // AuthService.swift // SwApp // // Created by Juan Alvarez on 11/24/21. // // Use to Authenticate users in Firebase //Use to handle User accounts in Firebase import Foundation import FirebaseAuth import FirebaseFirestore // Database let DB_BASE = Firestore.firestore() // NOTE: Global variable, check if we want to actually use it across files. class AuthService { //MARK: PROPERTIES static let instance = AuthService() private var REF_USERS = DB_BASE.collection("users") // NOTE: Title of the folders, its private to be accessible only in this Auth Service file //MARK: AUTH USER FUNCTIONS func logInUserToFirebase(credential: AuthCredential, handler: @escaping (_ providerID: String?, _ isError: Bool) -> ()) { Auth.auth().signIn(with: credential) { (result, error) in // Check for errors if error != nil { print("Error logging into Firebase") handler(nil, true) return } // Check for provider ID guard let providerID = result?.user.uid else { print("Error getting provider ID") handler(nil, true) return } // Success connection to Firebase handler(providerID, false) // Handler used to be called whenever we want, unlike the return function that gets called immediately. Used because we are going to have wait time during the auth process and don't need to return results immediately. } } func logInUserToApp(userID: String, handler: @escaping (_ success: Bool) -> ()) { // Get the users info getUserInfo(forUserID: userID) { returnedName, returnedBio in if let name = returnedName, let bio = returnedBio { // Success print("Success getting user info while loggin in") handler(true) DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { // Set userDefaults one second after loggin them in // Set the users info into our app UserDefaults.standard.set(userID, forKey: CurrentUserDefaults.userID) UserDefaults.standard.set(bio, forKey: CurrentUserDefaults.bio) UserDefaults.standard.set(name, forKey: CurrentUserDefaults.displayName) } } else { // Error print("Error getting user info while loggin in") handler(false) } } } func createNewUserInDatabase(name: String, email: String, providerID: String, provider: String, profileImage: UIImage, handler: @escaping (_ userID: String?) -> ()) { // Set up a user Document with the user Collection, for Firestore Database let document = REF_USERS.document() let userID = document.documentID //Upload profile image to Storage ImageManager.instance.uploadProfileImage(userID: userID, image: profileImage) // Upload profile data to Firestore let userData: [String: Any] = [ DatabaseUserField.displayName : name, DatabaseUserField.email : email, DatabaseUserField.providerID : providerID, DatabaseUserField.provider : provider, DatabaseUserField.userID : userID, DatabaseUserField.bio : "", DatabaseUserField.dateCreated : FieldValue.serverTimestamp(), ] // Put data in the document document.setData(userData) { (error) in if let error = error { // Error print("Error uploading data to user document. \(error)") handler(nil) } else { // Success handler(userID) } } } // MARK: GET USER FUNCTIONS // forUserID is the global name, and userID is the local name. func getUserInfo(forUserID userID: String, handler: @escaping (_ name: String?, _ bio: String?) -> ()) { REF_USERS.document(userID).getDocument { (documentSnapshot, error) in if let document = documentSnapshot, let name = document.get(DatabaseUserField.displayName) as? String, let bio = document.get(DatabaseUserField.bio) as? String { print("Success getting user info") handler(name, bio) return } else { print("Error getting user info") handler(nil,nil) return } } } }