Hi everyone,
So I’m currently having some issues with these blocks of code:
- A function to get the requested user by using their id’s. This function firstly checks the local users who have already been fetched, and then, if not all the users could be found in the local users, it checks the database where all the users are stored.
- A function to fetch the requested users from databases using their id’s. So this is the function that is used in the function above.
Here are my two function:
The first function which check the local users and calls the other function
/// Given a list of user ids, returns a list of user objects with the same user id, and fetches any users who are not a contact
func getUsers(ids: [String]) -> [User] {
// Ids representing contacts
var contactIds:[String] = []
// Ids representing other users
var userIds:[String] = []
// The merged array of users
@State var foundUsers: [User] = []
// Put these ids in the right array
for id in ids {
switch self.userIsContact(id: id) {
case true:
contactIds.append(id)
case false:
userIds.append(id)
}
}
if !contactIds.isEmpty {
// Get these users
foundUsers.append(contentsOf: self.getContacts(ids: contactIds))
}
if !userIds.isEmpty {
// Fetch these users
// Here is the call to my second function
databaseService.getUsers(ids: userIds) { users in
// Here is the issue
// Append these users to the found users
foundUsers.append(contentsOf: users)
}
}
// Set these users to the users const. in the main thread
return foundUsers
}
The second function which performs a query to the database and returns the found users
/// Retrieves all the users by the given ids
func getUsers(ids: [String], completion: @escaping ([User]) -> Void) {
if !(ids.isEmpty) {
// Create query
let query = Firestore.firestore().collection("users").whereField(FieldPath.documentID(), in: ids)
// Perform the query
query.getDocuments { snapshot, error in
if snapshot != nil && error == nil {
// Convert the document into users
let users: [User] = snapshot!.documents.map { (try? $0.data(as: User.self)) ?? User() }.filter { $0.id != nil }
// Return the ussers
completion(users)
}
}
} else {
completion([User]())
}
}
Now my problem with this code is in the first function, in the completion of the seconds function. (I’ve indicated this place in the code.)
The problem is the following: when I assign the value I get in this completion, being users
, to the foundUsers
array, the value is actually assigned to that variable. But when the code after the completion is ran, the value which was assigned to foundUsers
in the completion, is disappeared. So the variable doesn’t hold that data anymore.
I don’t know how this happens, but it happens most of the time when I use a completion to return fetched data.
So if anyone could help me figure this out, it would be greatly appreciated!