I'm using swift's DispatchGroup() to help orchestrate a for loop that
- finds a document in firesbase
- converts the document to a custom object
- appends the custom object to an array
With each pass, the function ends up appending each object twice to the array and I can't understand why. Here is the function...
func getFriends() {
// Initialize the DispatchGroup
let group = DispatchGroup()
// the myFriends array contains documentIDs that I am using to fetch documents from firebase
//
for pid in myFriendObj.myFriends {
group.enter()
_ = Firestore.firestore().collection("Players")
.whereField(FieldPath.documentID(), isEqualTo: pid)
.addSnapshotListener { [self] querySnapshot, error in
if let error = error {
print("Error getting > Players: \(error.localizedDescription)")
return
}
guard let querySnapshot = querySnapshot else { return }
self.players.append(
contentsOf: querySnapshot.documents.compactMap { document in
try? document.data(as: UserProfile.self)
})
group.leave()
}
}
group.notify(queue: DispatchQueue.global(qos: .background)) {
// I'm currently eliminating the dups via this fancy extends method.
self.players = self.players.removeDuplicates()
}
}
:: UPDATE ::
Still no luck on this - i've even removed dispatchgroup and the snapshotlistener callbacks and still this code calls get() twice when an instance of the class is instantiated. Here is the new, more simple code...
class FriendRepository: ObservableObject {
private let store = Firestore.firestore()
private let friendPath: String = "MyFriends"
@Published var friendIDs: [String] = []
var userId = ""
private let authenticationService = AuthenticationService()
private var cancellables: Set<AnyCancellable> = []
init() {
authenticationService.$user
.compactMap { user in
user?.uid
}
.assign(to: \.userId, on: self)
.store(in: &cancellables)
authenticationService.$user
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
self?.get()
}
.store(in: &cancellables)
}
func get( ) {
store.collection(friendPath).document(userId).getDocument {(document, error) in
let result = Result {
try document?.data(as: Friends.self)
}
switch result {
case .success(let f):
if let f = f {
print("friends:>> \(f.myFriends)")
self.friendIDs = f.myFriends
} else {
print("Document does not exist")
}
case .failure(let error):
print("Error decoding city: \(error)")
}
}
}
When a new instance run init(), I see this in the console... It prints the friends:>> statement twice
friends:>> ["PHyUe6mAc3LodM5guJJU"]
friends:>> ["PHyUe6mAc3LodM5guJJU"]