I'm currently dealing with this problem. I have Firestore database. My goal is to fill friends array with User entities after being fetched. I call fetchFriends, which fetches currently logged user, that has friends array in it (each item is ID of friend). friends array is then looped and each ID of friend is fetched and new entity User is made. I want to map this friends array to friends Published variable. What I did there does not work and I'm not able to come up with some solution.
Firestore DB
User
- name: String
- friends: [String]
User model
struct User: Identifiable, Codable {
@DocumentID var id: String?
var name: String?
var email: String
var photoURL: URL?
var friends: [String]?
}
User ViewModel
@Published var friends = [User?]()
func fetchFriends(uid: String) {
let userRef = db.collection("users").document(uid)
userRef.addSnapshotListener { documentSnapshot, error in
do {
guard let user = try documentSnapshot?.data(as: User.self) else {
return
}
self.friends = user.friends!.compactMap({ friendUid in
self.fetchUserAndReturn(uid: friendUid) { friend in
return friend
}
})
}
catch {
print(error)
}
}
}
func fetchUserAndReturn(uid: String, callback:@escaping (User)->User) {
let friendRef = db.collection("users").document(uid)
friendRef.getDocument { document, error in
callback(try! document?.data(as: User.self) as! User)
}
}
printstatements everywhere and confirm that the document is actually downloaded, that theUserobject is actually initialized, that the array is actually looped, etc. Somewhere along the way, it will print incorrectly and let us know where that is.self.friendsis expecting to get populated by repeating calls tofetchUserAndReturnwhich is also asynchronous (or, specifically, thegetDocumentfunction within it is) and won't return aUserto thecompactMaplike expected?self.fetchUserAndReturnI now get this error message: "Cannot convert value of type '()' to closure result type 'User??'"