getting proper listener activation instead of having 100 listeners on

also brute force log out navigation as it's not working

fixing little things here and there and getting organized
This commit is contained in:
talksik
2021-12-23 23:51:17 -08:00
parent aafe544e71
commit 4b2208eae6
4 changed files with 77 additions and 24 deletions
+50 -19
View File
@@ -39,6 +39,9 @@ final class AuthSessionStore: ObservableObject, SessionStore {
// transformed data for the views // transformed data for the views
@Published var friendMessagesDict: [String: [Message]] = [:] @Published var friendMessagesDict: [String: [Message]] = [:]
private var dataListeners: [ListenerRegistration] = []
private var listenersActive = false // false on app/processes killed
// TODO: temporary...should not have this here // TODO: temporary...should not have this here
private var db = Firestore.firestore() private var db = Firestore.firestore()
@@ -117,10 +120,10 @@ final class AuthSessionStore: ObservableObject, SessionStore {
} }
func logOut() { func logOut() {
let firebaseAuth = Auth.auth()
do { do {
try firebaseAuth.signOut() try Auth.auth().signOut()
self.deinitDataListeners()
} catch let signOutError as NSError { } catch let signOutError as NSError {
print("Error signing out: %@", signOutError) print("Error signing out: %@", signOutError)
} }
@@ -132,6 +135,10 @@ final class AuthSessionStore: ObservableObject, SessionStore {
} }
} }
func getCurrentUserId() -> String? {
return Auth.auth().currentUser?.uid
}
func setupAuthListen() { func setupAuthListen() {
// monitor authentication changes using firebase // monitor authentication changes using firebase
self.handler = Auth.auth().addStateDidChangeListener { [weak self] res, authUser in self.handler = Auth.auth().addStateDidChangeListener { [weak self] res, authUser in
@@ -140,6 +147,7 @@ final class AuthSessionStore: ObservableObject, SessionStore {
guard let self = self else { return } guard let self = self else { return }
self.sessionState = authUser == nil ? SessionState.isLoggedOut : SessionState.isAuthenticated self.sessionState = authUser == nil ? SessionState.isLoggedOut : SessionState.isAuthenticated
print("set the session state to \(self.sessionState)")
// get the user from the auth table in firebase auth // get the user from the auth table in firebase auth
if let uid = authUser?.uid { if let uid = authUser?.uid {
@@ -147,9 +155,6 @@ final class AuthSessionStore: ObservableObject, SessionStore {
print("auth listener: Got user: \(uid)") print("auth listener: Got user: \(uid)")
print("auth listener: phone number: \(authUser?.phoneNumber)") print("auth listener: phone number: \(authUser?.phoneNumber)")
// MARK: data listeners for entire environment
self.activateMainDataListeners(userId: uid)
} else { } else {
// if we don't have a user, set our session to nil // if we don't have a user, set our session to nil
self.user = nil self.user = nil
@@ -172,14 +177,9 @@ extension UIApplication {
} }
struct MasterUserFriendsMessagesModel {
}
// activate data listeners for the main data throughout the app
extension AuthSessionStore { extension AuthSessionStore {
// get all my friends // get all my friends
// traverse all my friends, and put them into the friendsDict // traverse all my friends, and put them into the friendsDict
@@ -195,12 +195,29 @@ extension AuthSessionStore {
// I send a new message to sarth -> goes to messages database -> notification to sarth // I send a new message to sarth -> goes to messages database -> notification to sarth
// sarth's data looks like this: [arjun: [...arjun's message, sarth's reply...]] // sarth's data looks like this: [arjun: [...arjun's message, sarth's reply...]]
func activateMainDataListeners() {
// do nothing if the snapshots are already alive
if self.listenersActive {
print("listeners already alive...no point reinitiating")
return
}
// extra validation to make sure that we are authenticated although should be if this is called
if self.sessionState != SessionState.isAuthenticated {
print("can't initiate data listeners...user not authenticated")
return
}
// can't get proper listeners working if don't have current user's id
let currUserId = self.getCurrentUserId()
if currUserId == nil {
print("no user id available to initiate data listeners")
return
}
private func activateMainDataListeners(userId: String) {
// MARK: keeping the @Published user object updated // MARK: keeping the @Published user object updated
// TODO: THIS WON"T UPDATE VIEW since user is a reference type...can manually publish...research and learn more // TODO: THIS WON"T UPDATE VIEW since user is a reference type...can manually publish...research and learn more
self.firestoreService.getUserRealtime(userId: userId) {[weak self] realtimeUpdatedUser in self.firestoreService.getUserRealtime(userId: currUserId!) {[weak self] realtimeUpdatedUser in
if realtimeUpdatedUser != nil { if realtimeUpdatedUser != nil {
print("up to date user: \(realtimeUpdatedUser)") print("up to date user: \(realtimeUpdatedUser)")
self?.user = realtimeUpdatedUser self?.user = realtimeUpdatedUser
@@ -218,7 +235,7 @@ extension AuthSessionStore {
// order: when the relationship was created...also easy for user // order: when the relationship was created...also easy for user
// limit: for my protection of db costs lol // limit: for my protection of db costs lol
// TODO: use the indexes I created // TODO: use the indexes I created
db.collection("user_friends").whereField("userId", isEqualTo: userId).limit(to: 100) let friendsListener = db.collection("user_friends").whereField("userId", isEqualTo: currUserId).limit(to: 100)
.addSnapshotListener { querySnapshot, error in .addSnapshotListener { querySnapshot, error in
guard let documents = querySnapshot?.documents else { guard let documents = querySnapshot?.documents else {
print("Error fetching user's friends: \(error!)") print("Error fetching user's friends: \(error!)")
@@ -281,7 +298,7 @@ extension AuthSessionStore {
// limit: because each user should have most 12 friends and so would at most need 24 messages to show turns and all that...save myself from hackers here...unless a user gets 100 messages from someone, and that too at least they will be ordered // limit: because each user should have most 12 friends and so would at most need 24 messages to show turns and all that...save myself from hackers here...unless a user gets 100 messages from someone, and that too at least they will be ordered
// SOLUTION: composite with array // SOLUTION: composite with array
db.collection("messages").whereField("senderIdReceiverIdComposite", arrayContains: userId).order(by: "sentTimestamp", descending: true).limit(to: 100) let messagesListener = db.collection("messages").whereField("senderIdReceiverIdComposite", arrayContains: currUserId).order(by: "sentTimestamp", descending: true).limit(to: 100)
.addSnapshotListener { querySnapshot, error in .addSnapshotListener { querySnapshot, error in
guard let documents = querySnapshot?.documents else { guard let documents = querySnapshot?.documents else {
print("error in fetching messages: \(error!)") print("error in fetching messages: \(error!)")
@@ -304,7 +321,7 @@ extension AuthSessionStore {
// this means it's most likely someone new (never had user_friend relationship before) messaging for the user's inbox // this means it's most likely someone new (never had user_friend relationship before) messaging for the user's inbox
// TODO: prolly want to make a call to get this sender user details for the inbox, but they should either be in the friendsArr or their are not a friend so won't be there // TODO: prolly want to make a call to get this sender user details for the inbox, but they should either be in the friendsArr or their are not a friend so won't be there
// also add in any messages where I am the sender // also add in any messages where I am the sender
if currMessage!.senderId == userId { // if I am the sender if currMessage!.senderId == currUserId { // if I am the sender
if self.friendMessagesDict[currMessage!.receiverId] == nil { if self.friendMessagesDict[currMessage!.receiverId] == nil {
self.friendMessagesDict[currMessage!.receiverId] = [currMessage!] self.friendMessagesDict[currMessage!.receiverId] = [currMessage!]
} else { } else {
@@ -318,7 +335,6 @@ extension AuthSessionStore {
self.friendMessagesDict[currMessage!.senderId]?.append(currMessage!) self.friendMessagesDict[currMessage!.senderId]?.append(currMessage!)
} }
} }
} }
self.objectWillChange.send() self.objectWillChange.send()
@@ -331,9 +347,24 @@ extension AuthSessionStore {
return nil return nil
} }
} }
self.listenersActive = true
// adding listeners to be able to deinit later
// TODO: make sure to have this listener avaible available to deinit as well
// self.dataListeners.append(currUserListener)
self.dataListeners.append(messagesListener)
self.dataListeners.append(friendsListener)
} }
private func deinitDataListeners() { func deinitDataListeners() {
for listener in self.dataListeners {
listener.remove()
}
print("deactivated listeners!")
self.listenersActive = false
} }
} }
@@ -58,6 +58,8 @@ struct CircleNavigationView: View {
self.authSessionStore.logOut() self.authSessionStore.logOut()
// TODO: brute force navigating out as it's not working
self.navigationStack.push(RouterView())
// once logged out, then the listener will listen and router view will take care of us thereafter // once logged out, then the listener will listen and router view will take care of us thereafter
} label: { } label: {
Label("log out", systemImage: "rectangle.portrait.and.arrow.right") Label("log out", systemImage: "rectangle.portrait.and.arrow.right")
@@ -116,7 +116,7 @@ struct InnerCircleView: View {
Button { Button {
self.alertActive.toggle() self.alertActive.toggle()
self.alertText = "👆🏼It's simple!" self.alertText = "👆🏼It's simple!"
self.alertSubtext = "Press and hold to send a message. \n Tap to listen!" self.alertSubtext = "Press and hold on a friend to send a message. \n Tap on them to listen!"
} label: { } label: {
Label("help!🙉", systemImage: "questionmark.circle") Label("help!🙉", systemImage: "questionmark.circle")
.font(.caption) .font(.caption)
@@ -139,6 +139,18 @@ struct InnerCircleView: View {
} message: { } message: {
Text(self.alertSubtext) Text(self.alertSubtext)
} }
.onAppear {
// activate 3 data listeners once for authsessionstore/usermanager if not already called, but authsessionstore will handle that
self.authSessionStore.activateMainDataListeners()
// save device token
}
// .onDisappear {
// print("deiniting data listeners, but current data should still be cached!")
//
// // deactivate all data listeners
// self.authSessionStore.deinitDataListeners()
// }
} }
} }
@@ -33,6 +33,10 @@ class InnerCircleViewModel: ObservableObject {
} }
} }
}
// audio stuff
extension InnerCircleViewModel {
func startRecording() { func startRecording() {
let filePath = getTemporaryDirectory().appendingPathComponent("\(UUID().uuidString).m4a") let filePath = getTemporaryDirectory().appendingPathComponent("\(UUID().uuidString).m4a")
@@ -98,3 +102,7 @@ class InnerCircleViewModel: ObservableObject {
} }
// handling saving device token for notifications
extension InnerCircleViewModel {
}