Первая проблема с кодом в вопросе заключается в том, что Firestore является асинхронным.
Любой код, следующий за закрытием, будет выполнен перед кодом в закрытии. Для извлечения данных с сервера требуется время, и код внутри замыкания запускается после извлечения этих данных.
Так что эту строку
if containsDay == true {
необходимо переместить.
Ответ Фрэнка превосходен, но другое решение - использовать экранирование вместе с перерывом
Предположим, что мы хотим получить uid пользователя - в этом случае мы перебираем узел user, чтобы найти Боба.
users
uid_0
name: "Frank"
uid_1
name: "Bill"
uid_2
name: "Bob"
Вот код, который мы вызываем нашей функцией с
self.lookForBobsUid(completion: { bobsUid in
print("Bob's uid is: \(bobsUid)")
})
, а затем функция, которая читает все пользователи, перебирает их, а затем, когда мы находим Боба, возвращает Bobs uid и вырваться из l oop.
func lookForBobsUid(completion: @escaping ( (String) -> Void ) ) {
let usersCollection = self.db.collection("users")
usersCollection.getDocuments(completion: { snapshot, error in
if let err = error {
print(err.localizedDescription)
return
}
guard let documents = snapshot?.documents else { return }
for doc in documents {
let uid = doc.documentID
let name = doc.get("name") as? String ?? "No Name"
print("checking name: \(name)")
if name == "Bob" {
print(" found Bob, leaving loop")
completion(uid)
break
}
}
})
print("note this line will print before any users are iterated over")
}
Обратите внимание, что я добавил строку в конце кода, чтобы продемонстрировать природу асинхронных вызовов.
Все это сказано Вообще говоря, итерации по коллекциям для поиска чего-либо обычно можно избежать.
Похоже, вы ищете все, что разрешает до
self.daysOfWeek[self.picker.selectedRow(inComponent: 0)]
Если это так, было бы целесообразно запрос self.colRef для этого элемента вместо итерации, чтобы найти его; это будет намного быстрее и потребляет меньше ресурсов, а также будет масштабируемым - что если бы было 100 000 узлов для перебора!