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
+54 -23
View File
@@ -39,6 +39,9 @@ final class AuthSessionStore: ObservableObject, SessionStore {
// transformed data for the views
@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
private var db = Firestore.firestore()
@@ -117,10 +120,10 @@ final class AuthSessionStore: ObservableObject, SessionStore {
}
func logOut() {
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
try Auth.auth().signOut()
self.deinitDataListeners()
} catch let signOutError as NSError {
print("Error signing out: %@", signOutError)
}
@@ -132,6 +135,10 @@ final class AuthSessionStore: ObservableObject, SessionStore {
}
}
func getCurrentUserId() -> String? {
return Auth.auth().currentUser?.uid
}
func setupAuthListen() {
// monitor authentication changes using firebase
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 }
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
if let uid = authUser?.uid {
@@ -147,9 +155,6 @@ final class AuthSessionStore: ObservableObject, SessionStore {
print("auth listener: Got user: \(uid)")
print("auth listener: phone number: \(authUser?.phoneNumber)")
// MARK: data listeners for entire environment
self.activateMainDataListeners(userId: uid)
} else {
// if we don't have a user, set our session to nil
self.user = nil
@@ -172,14 +177,9 @@ extension UIApplication {
}
struct MasterUserFriendsMessagesModel {
}
// activate data listeners for the main data throughout the app
extension AuthSessionStore {
// get all my friends
// 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
// sarth's data looks like this: [arjun: [...arjun's message, sarth's reply...]]
private func activateMainDataListeners(userId: String) {
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
}
// 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
self.firestoreService.getUserRealtime(userId: userId) {[weak self] realtimeUpdatedUser in
self.firestoreService.getUserRealtime(userId: currUserId!) {[weak self] realtimeUpdatedUser in
if realtimeUpdatedUser != nil {
print("up to date user: \(realtimeUpdatedUser)")
self?.user = realtimeUpdatedUser
@@ -218,7 +235,7 @@ extension AuthSessionStore {
// order: when the relationship was created...also easy for user
// limit: for my protection of db costs lol
// 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
guard let documents = querySnapshot?.documents else {
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
// 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
guard let documents = querySnapshot?.documents else {
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
// 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
if currMessage!.senderId == userId { // if I am the sender
if currMessage!.senderId == currUserId { // if I am the sender
if self.friendMessagesDict[currMessage!.receiverId] == nil {
self.friendMessagesDict[currMessage!.receiverId] = [currMessage!]
} else {
@@ -318,7 +335,6 @@ extension AuthSessionStore {
self.friendMessagesDict[currMessage!.senderId]?.append(currMessage!)
}
}
}
self.objectWillChange.send()
@@ -331,9 +347,24 @@ extension AuthSessionStore {
return nil
}
}
}
private func deinitDataListeners() {
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)
}
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()
// 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
} label: {
Label("log out", systemImage: "rectangle.portrait.and.arrow.right")
@@ -116,7 +116,7 @@ struct InnerCircleView: View {
Button {
self.alertActive.toggle()
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("help!🙉", systemImage: "questionmark.circle")
.font(.caption)
@@ -139,6 +139,18 @@ struct InnerCircleView: View {
} message: {
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() {
let filePath = getTemporaryDirectory().appendingPathComponent("\(UUID().uuidString).m4a")
@@ -98,3 +102,7 @@ class InnerCircleViewModel: ObservableObject {
}
// handling saving device token for notifications
extension InnerCircleViewModel {
}