I want to get all Users near by my own Location.
I wrote following code in the location Manager didUpdateLocation function.
First I grabbed my own location as a CCLocationCoridnate2D.
if let location = locations.last{ let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
Than I made a query to get all users near by my location.
let geofireRef = Database.database().reference()
let geoFire = GeoFire(firebaseRef: geofireRef)
geoFire.setLocation(CLLocation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude), forKey: "test")
let centerQuery = CLLocation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let circleQuery = geoFire.query(at: centerQuery, withRadius: 5)
var queryHandle = circleQuery.observe(.keyEntered, with: { (key: String!, location: CLLocation!) in
print("Key '\(key)' entered the search area and is at location '\(location)'")
})
If I now want to replace "test" with my actual user (userdocid) it won't work.
How I grab my User:
Firestore.firestore().collection("users").whereField("uid", isEqualTo: Auth.auth().currentUser?.uid ?? "x")
.getDocuments { (querySnapshot, err) in
if err != nil {
print("Failed")
return
}
let userdocid = querySnapshot!.documents[0].documentID
The App is crashing because of empty NSArray.
Thank you in advance Mark
This answer depends on how you're user data is stored but if you're storing users with their documentId as the users uid then just
let uid = Auth.auth().currentUser!.uid //should safe unwrap that optional
then
geoFire.setLocation(CLLocation(..., forKey: uid)
however, if you want to get it as you're doing in the question
let uid = Auth.auth().currentUser!.uid
let usersCollection = Firestore.firestore().collection("users")
.whereField("uid", isEqualTo: uid)
usersCollection.getDocument(completion: { documentSnapshot, error in
if let err = error {
print(err.localizedDescription)
return
}
guard let docs = documentSnapshot?.documents else { return }
let thisUserUid = docs[0].documentID
print(thisUserUid)
})
But again, that's a bit redundant as it wound indicate storing the uid in both the documentId as well as a child field, which is unnecessary:
users
uid_0 //the documentId
name: "Users name"
uid: "uid_0" //not needed
The problem appers to be actually getting the center point - e.g. if it's not stored, then when read, it will be empty and you'll get that error.
So you have to store it to start with
geoFire.setLocation(CLLocation(latitude: 37.7853889, longitude: -122.4056973), forKey: uid) { (error) in
if (error != nil) {
print("An error occured: \(error)")
} else {
print("Saved location successfully!")
}
}
Once you successfully stored a center point (your location), and then retrieved it, then the actual query should be
let center = CLLocation(userLocation)
geoFire.queryAtLocation(center, withRadius: 20);
Oh, and a very important thing is the setLocation is asynchronous; it takes time for the server to store the data. You should really be working with the data within the closure
geoFire.setLocation(CLLocation(latitude: 37.7853889, longitude: -122.4056973), forKey: uid) { (error) in
// data is now valid so perform your query
}