I am creating a fitness app where you can favorite trainer accounts and when you favorite a trainer account I want to add all workouts posted by that trainer to the current user's feed.
When you favorite a trainer account I use this function to add the workouts to a collection on firestore:
func addToUserFeed() {
guard let trainerUid = trainer.id else { return }
guard let currentUid = AuthViewModel.shared.userSession?.uid else { return }
COLLECTION_WORKOUTS.whereField("ownerUid", isEqualTo: trainerUid).addSnapshotListener { snapshot, _ in
guard let workoutIDs = snapshot?.documents.map({ $0.documentID }) else { return }
workoutIDs.forEach { id in
COLLECTION_USERS.document(currentUid).collection("user-feed").document(id).setData([:])
}
}
}
Similarly, when you unfavorite a trainer I am removing those workouts from the user feed collection with this function:
func removeFromUserFeed() {
guard let trainerUid = trainer.id else { return }
guard let currentUid = AuthViewModel.shared.userSession?.uid else { return }
COLLECTION_WORKOUTS.whereField("ownerUid", isEqualTo: trainerUid).addSnapshotListener { snapshot, _ in
guard let workoutIDs = snapshot?.documents.map({ $0.documentID }) else { return }
workoutIDs.forEach { id in
COLLECTION_USERS.document(currentUid).collection("user-feed").document(id).delete()
}
}
}
Then to display these workouts on the feed page view in my app I fetch all the workouts in the user-feed collection on firestore with this function:
//FETCH WORKOUTS SAVED BY THE USER
func fetchFavoriteWorkouts() {
guard let currentUid = AuthViewModel.shared.userSession?.uid else { return }
COLLECTION_USERS.document(currentUid).collection("user-feed").addSnapshotListener { snapshot, _ in
guard let workoutIDs = snapshot?.documents.map({ $0.documentID }) else { return }
//THIS MAY CAUSE AN UNNECCESSARY AMOUNT OF WRITES TO THE APP
self.workouts.removeAll()
workoutIDs.forEach { id in
COLLECTION_WORKOUTS.document(id).addSnapshotListener { snapshot, _ in
guard let workout = try? snapshot?.data(as: Workout.self) else { return }
self.workouts.append(workout)
print("\(workoutIDs)")
}
}
}
}
This is what the firestore collection looks like for user-feed. It adds workout ID documents to the collection that match up with workouts posting by the trainer you just favorited:
This is working properly in a sense that when you favorite a trainer account it correctly adds multiple documents to the user-feed collection which correspond to workout IDs posted by the trainer you just favorited, however, when you favorite a trainer account the app just closes (not really crashes), and then when you re-open the app the user-feed correctly displays the workouts from trainers you have favorited.
Is there anything in my code that may be causing this random app close when you favorite a trainer?
I understand that this code may not be the most efficient, but I am really not focused on fixing that at the moment, just want to fix the random app close out.
Edit: The crash only happens when I favorite a trainer that has multiple workouts posted. So I guess something causes the crash when I add multiple documents to a collection at once? Because if I favorite a trainer that only has one workout then it adds that workout to my feed without crashing at all.
CodePudding user response:
the problem is caused by the listener getting called each time a workout is added to workout list and adding duplicated values to the list .
change addSnapshotListener to getDocuments fetchFavoriteWorkouts() and call this fetch function inside .onAppear() in feed View