From 71f5aff78c0781d630f41ac87437819e883b5c9c Mon Sep 17 00:00:00 2001 From: talksik Date: Sat, 18 Dec 2021 17:28:11 -0800 Subject: [PATCH] debugging phase of user creation process --- nirvana-ios.xcodeproj/project.pbxproj | 8 +++ nirvana-ios/Globals/CustomExtensions.swift | 23 +++++++++ nirvana-ios/Models/Messages.swift | 15 +++--- nirvana-ios/Models/User.swift | 30 +++++++---- .../Repositories/FirestoreService.swift | 50 ++++++++++++++++++- nirvana-ios/Repositories/ServiceState.swift | 17 +++++++ .../PhoneCodeVerificationView.swift | 14 ++++-- .../PhoneVerificationViewModel.swift | 33 ++++++------ 8 files changed, 154 insertions(+), 36 deletions(-) create mode 100644 nirvana-ios/Globals/CustomExtensions.swift create mode 100644 nirvana-ios/Repositories/ServiceState.swift diff --git a/nirvana-ios.xcodeproj/project.pbxproj b/nirvana-ios.xcodeproj/project.pbxproj index 5f912c1..61004bf 100644 --- a/nirvana-ios.xcodeproj/project.pbxproj +++ b/nirvana-ios.xcodeproj/project.pbxproj @@ -64,6 +64,8 @@ 89F18AE6276E881900115B1E /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 89F18AE5276E881900115B1E /* FirebaseStorage */; }; 89F18AE8276E881900115B1E /* FirebaseStorageCombine-Community in Frameworks */ = {isa = PBXBuildFile; productRef = 89F18AE7276E881900115B1E /* FirebaseStorageCombine-Community */; }; 89F18AEA276E881900115B1E /* FirebaseStorageSwift-Beta in Frameworks */ = {isa = PBXBuildFile; productRef = 89F18AE9276E881900115B1E /* FirebaseStorageSwift-Beta */; }; + 89F18AEC276E92BF00115B1E /* CustomExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89F18AEB276E92BF00115B1E /* CustomExtensions.swift */; }; + 89F18AEE276EB55C00115B1E /* ServiceState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89F18AED276EB55C00115B1E /* ServiceState.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -109,6 +111,8 @@ 89F05BA3276ACC060002E9C7 /* ContactService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactService.swift; sourceTree = ""; }; 89F05BA5276ACD830002E9C7 /* ContactsPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsPickerView.swift; sourceTree = ""; }; 89F1386C2767EB19006680ED /* SignInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInView.swift; sourceTree = ""; }; + 89F18AEB276E92BF00115B1E /* CustomExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomExtensions.swift; sourceTree = ""; }; + 89F18AED276EB55C00115B1E /* ServiceState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceState.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -245,6 +249,7 @@ 891A15FC276566B800B26659 /* constants.swift */, 89BDCDE427695DB900577829 /* NirvanaImage.swift */, 89BDCDE62769616600577829 /* UIImage+Extension.swift */, + 89F18AEB276E92BF00115B1E /* CustomExtensions.swift */, ); path = Globals; sourceTree = ""; @@ -305,6 +310,7 @@ isa = PBXGroup; children = ( 89AD557B276DF86A001658E0 /* FirestoreService.swift */, + 89F18AED276EB55C00115B1E /* ServiceState.swift */, ); path = Repositories; sourceTree = ""; @@ -479,6 +485,8 @@ 891A16132765A44300B26659 /* ChatsCarouselViewModel.swift in Sources */, 89F05B9B276A87920002E9C7 /* ContactsViewModel.swift in Sources */, 89AD5573276DD790001658E0 /* SplashView.swift in Sources */, + 89F18AEC276E92BF00115B1E /* CustomExtensions.swift in Sources */, + 89F18AEE276EB55C00115B1E /* ServiceState.swift in Sources */, 891A15E127653A7000B26659 /* nirvana_iosApp.swift in Sources */, 89BCABED276D2B05009E9B10 /* WavesGlassBackgroundView.swift in Sources */, 89F05BA6276ACD830002E9C7 /* ContactsPickerView.swift in Sources */, diff --git a/nirvana-ios/Globals/CustomExtensions.swift b/nirvana-ios/Globals/CustomExtensions.swift new file mode 100644 index 0000000..6646f1b --- /dev/null +++ b/nirvana-ios/Globals/CustomExtensions.swift @@ -0,0 +1,23 @@ +// +// CustomExtensions.swift +// nirvana-ios +// +// Created by Arjun Patel on 12/18/21. +// + +import Foundation + +extension String { + // custom function to give (949)920-0392 and get out the right thing + func applyPatternOnNumbers(pattern: String, replacementCharacter: Character) -> String { + var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression) + for index in 0 ..< pattern.count { + guard index < pureNumber.count else { return pureNumber } + let stringIndex = String.Index(utf16Offset: index, in: pattern) + let patternCharacter = pattern[stringIndex] + guard patternCharacter != replacementCharacter else { continue } + pureNumber.insert(patternCharacter, at: stringIndex) + } + return pureNumber + } +} diff --git a/nirvana-ios/Models/Messages.swift b/nirvana-ios/Models/Messages.swift index c8ebeb3..8dc5d24 100644 --- a/nirvana-ios/Models/Messages.swift +++ b/nirvana-ios/Models/Messages.swift @@ -6,15 +6,16 @@ // import Foundation +import FirebaseFirestoreSwift -public struct Messages: Codable { - let id: String - let senderId: String - let receiverId: String +struct Messages: Identifiable, Codable { + @DocumentID var id: String? + var senderId: String + var receiverId: String - let sentTimestamp:Date - let listenedTimestamp:Date - let audioDataUrl:String + @ServerTimestamp var sentTimestamp:Date? + @ServerTimestamp var listenedToTimestamp:Date? + var audioDataUrl:String? } diff --git a/nirvana-ios/Models/User.swift b/nirvana-ios/Models/User.swift index 4f3fea1..c9582c9 100644 --- a/nirvana-ios/Models/User.swift +++ b/nirvana-ios/Models/User.swift @@ -6,18 +6,28 @@ // import Foundation -import SwiftUI +import FirebaseFirestoreSwift -public struct User: Codable { - let id: String - let firstName: String - let lastName: String? - let phoneNumber: String? - let emailAddress:String? - let avatar:String? +struct User: Identifiable, Codable { + @DocumentID var id: String? + var firstName: String? + var lastName: String? + var phoneNumber: String? + var emailAddress:String? + var avatar:String? - let lastLoggedInTimestamp: Date - let createdTimestamp: Date + @ServerTimestamp var lastLoggedInTimestamp: Date? + @ServerTimestamp var createdTimestamp: Date? + + enum CodingKeys: String, CodingKey { + case firstName + case lastName + case phoneNumber + case emailAddress + case avatar + case lastLoggedInTimestamp + case createdTimestamp + } } struct TestUser: Identifiable, Hashable { diff --git a/nirvana-ios/Repositories/FirestoreService.swift b/nirvana-ios/Repositories/FirestoreService.swift index 8fca406..a6af587 100644 --- a/nirvana-ios/Repositories/FirestoreService.swift +++ b/nirvana-ios/Repositories/FirestoreService.swift @@ -10,12 +10,58 @@ import Firebase import FirebaseFirestore class FirestoreService { - enum Collections: String { + enum Collection: String { case users = "users" case messages = "messages" case user_friends = "user_friends" // associating a user to } -// private var db = Firestore.firestore() + private var db = Firestore.firestore() + + func getUser(userId: String) -> User? { + let docRef = db.collection(Collection.users.rawValue).document(userId) + + var user:User? = nil + + docRef.getDocument { (document, error) in + if let document = document, document.exists { + user = try? document.data(as: User.self) + } else { + user = nil + } + } + + return user + } + + func createUser(user: User) { + do { + let _ = try db.collection(Collection.users.rawValue).addDocument(from: user) + } catch { + print("error in creating user \(error.localizedDescription)") + } + } + + func updateUser(user: User) -> ServiceState { + do { + if user.id != nil { + let _ = try db.collection(Collection.users.rawValue).document(user.id!).setData(from: user) + return ServiceState.success("Updated user in firestore service") + } else { + return ServiceState.error(ServiceError(description: "No user id given to firestore service")) + } + } catch { + print("error in creating user \(error.localizedDescription)") + return ServiceState.error(ServiceError(description: error.localizedDescription)) + } + } + + func getCollectionRef(_ collectionName: Collection) -> CollectionReference { + return db.collection(collectionName.rawValue) + } + + func getFirestoreServerTimestamp() -> FieldValue { + return FieldValue.serverTimestamp() + } } diff --git a/nirvana-ios/Repositories/ServiceState.swift b/nirvana-ios/Repositories/ServiceState.swift new file mode 100644 index 0000000..30661d6 --- /dev/null +++ b/nirvana-ios/Repositories/ServiceState.swift @@ -0,0 +1,17 @@ +// +// ServiceStates.swift +// nirvana-ios +// +// Created by Arjun Patel on 12/18/21. +// + +import Foundation + +enum ServiceState { + case error(ServiceError) + case success(String) +} + +struct ServiceError { + let description: String +} diff --git a/nirvana-ios/Views/PhoneVerification/PhoneCodeVerificationView.swift b/nirvana-ios/Views/PhoneVerification/PhoneCodeVerificationView.swift index 2cf34a9..c171565 100644 --- a/nirvana-ios/Views/PhoneVerification/PhoneCodeVerificationView.swift +++ b/nirvana-ios/Views/PhoneVerification/PhoneCodeVerificationView.swift @@ -12,6 +12,7 @@ import Firebase import FirebaseAuth struct PhoneCodeVerificationView: View { + @ObservedObject private var phoneverificationViewModel = PhoneVerificationViewModel() @EnvironmentObject private var navigationStack: NavigationStack @State var verificationCode = "" @@ -98,10 +99,17 @@ struct PhoneCodeVerificationView: View { print("user id that was authenticated is: \(userId)") print("user id that was authenticated is: \(userPhoneNumber)") - // get user from firestore using the firebase userid given, - // if not there, create - + // if for some reason firebase couldn't get basic user details + if userId == nil || userPhoneNumber == nil { + self.toastText = "⚠️ Error with Verification" + self.toastSubMessage = "Code is invalid. Please try again or re-enter your phone number in the previous page." + self.showToast.toggle() + + print((err?.localizedDescription)!) + return + } + self.phoneverificationViewModel.createOrUpdateUser(userId: userId!, phoneNumber: userPhoneNumber!) // then sending to next page self.navigationStack.push(OnboardingTrioView()) // verify code page diff --git a/nirvana-ios/Views/PhoneVerification/PhoneVerificationViewModel.swift b/nirvana-ios/Views/PhoneVerification/PhoneVerificationViewModel.swift index 0c1ce83..30aa775 100644 --- a/nirvana-ios/Views/PhoneVerification/PhoneVerificationViewModel.swift +++ b/nirvana-ios/Views/PhoneVerification/PhoneVerificationViewModel.swift @@ -9,26 +9,31 @@ import Foundation import FirebaseAuth final class PhoneVerificationViewModel : ObservableObject { + private var firestoreService = FirestoreService() + // TODO: add alert message handler here that publishes changes public func verifyPhoneAndSendSMS(phoneNumber: String) { // TODO: do some string validation here // do auth stuff from firebase + + } - -} - -extension String { - // custom function to give (949)920-0392 and get out the right thing - func applyPatternOnNumbers(pattern: String, replacementCharacter: Character) -> String { - var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression) - for index in 0 ..< pattern.count { - guard index < pureNumber.count else { return pureNumber } - let stringIndex = String.Index(utf16Offset: index, in: pattern) - let patternCharacter = pattern[stringIndex] - guard patternCharacter != replacementCharacter else { continue } - pureNumber.insert(patternCharacter, at: stringIndex) + public func createOrUpdateUser(userId: String, phoneNumber: String) { + // TODO: set all in a transaction or batch write + + // get user - 1 result set cost + var user = firestoreService.getUser(userId: userId) + print("user that was received from get: \(user?.id)") + + if user == nil {// if empty, create user - 1 result set cost..prolly higher cost + let newOrExistingUser = User(id: userId, phoneNumber: phoneNumber) + firestoreService.createUser(user: newOrExistingUser) + } else { // if not, change last logged in value + // assign to nil so that server can fill it in + user!.lastLoggedInTimestamp = nil + + let _ = firestoreService.updateUser(user: user!) } - return pureNumber } }