In my app, I use GeoFire to query users around user location.
It is a Tinder-like app, with cards, etc... I use KolodaView for cards.
Query function :
func queryUsers(searchRadius: Int, center: CLLocation) {
print("Query started")
let geofireRef = Database.database().reference().child("usersLocations")
let geoFire = GeoFire(firebaseRef: geofireRef)
let circleQuery = geoFire?.query(at: center, withRadius: Double(searchRadius))
_ = circleQuery?.observe(.keyEntered, with: { (result, location) in
print("User \(result!) found")
print("Adding user \(result!)")
addUser(userID: result!, completionHandler: { (success) in
print("User added")
})
})
}
Add user function :
func addUser(userID: String, completionHandler:@escaping (Bool) -> ()) {
let foundUsers = UserDefaults.standard.array(forKey: "foundUsers")
let databaseRef = Database.database().reference()
databaseRef.observeSingleEvent(of: .value, with: { (snapshot) in
if (foundUsers?.count)! < 20 {
// USERS
let users = (snapshot.value as? NSDictionary)?["users"] as! NSDictionary
// USER
let user = users[userID] as! NSDictionary
getFirstUserPicture(userID: userID, completionHandler: { (data) in
if let data = data {
DispatchQueue.main.async {
user.setValue(data, forKey: "picture")
// APPEND FOUND USERS ARRAY
var foundUsers = UserDefaults.standard.array(forKey: "foundUsers")
foundUsers?.append(user)
// STORE FOUND USERS ARRAY
UserDefaults.standard.set(foundUsers, forKey: "foundUsers")
UserDefaults.standard.synchronize()
// UPDATE CARD VIEW
if foundUsers?.count == 1 {
NotificationCenter.default.post(name: .loadCardView, object: nil)
} else {
NotificationCenter.default.post(name: .loadCardsInArray, object: nil)
}
// COMPLETION
completionHandler(true)
}
}
})
}
}) { (error) in
print(error.localizedDescription)
}
}
When I launch the app, the queryUsers function is called, the query
starts
Output
User 1XXXXXXXXXXXXXXXX found
Adding user 1XXXXXXXXXXXXXXXX
User 2XXXXXXXXXXXXXXXX found
Adding user 2XXXXXXXXXXXXXXXX
User added
User added
- User is found
- Adding user (call
addUserfunction)
The problem is that it didn't wait the addUser completion to call addUser for the second user found. The result is that in my KolodaView, there is the second user found two times
because I think the call of addUser for the second user found uses first user found parameters.
Is it possible to wait for the first addUser completion and start again the query ? Or just "pause" the query after the first user was found, and start it again after the completion of the first addUser call ?
Thanks for your help
Update 1
I tried the @Rlee128 solution but nothing changed, I have the same output :( :
// MARK: UPDATE USER LOCATION - FUNCTION
func updateUserLocation() {
let databaseRef = Database.database().reference().child("usersLocations")
let geoFire = GeoFire(firebaseRef: databaseRef)
let userID = UserDefaults.standard.string(forKey: "userID")!
let locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.startUpdatingLocation()
geoFire?.setLocation(locationManager.location, forKey: userID, withCompletionBlock: { (error) in
if error != nil {
print(error as Any)
} else {
// Location updated
}
})
}
// MARK: LOCATION MANAGER DELEGATE - FUNCTION
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
manager.delegate = nil
}
In then location manger didUpdateLocations set manager.delegate to = nil after you call manager.stopUpdatingLocation(). Let me know if you want me to show you how it looks in my code.