Retrieving Keys from Geofire Within Radius in Swift

Retrieving Keys From GeoFire within Radius in Swift

Figured it out

func geoFireQuery() {

let circleQuery = geoFire.query(at: self.myLocation, withRadius: 0.5)

_ = circleQuery!.observe(.keyEntered, with: { (key: String?, location: CLLocation?) in

print (key!)

})

circleQuery?.observeReady({
print("All initial data has been loaded and events have been fired!")

})

}

this seems to be giving me what I need. Now to reference those keys to the other part of the FBDB. :)

GeoFire Query on lists of data

I think you need to separate your GeoFire from your UserDatabase

To Set Locations call

geoFire.setLocation(CLLocation(latitude: 37.7853889, longitude: -122.4056973), forKey: **UserID** )

Then you create the Circle Query

let center = CLLocation(latitude: 37.7832889, longitude: -122.4056973)
var circleQuery = geoFire.queryAtLocation(center, withRadius: 0.6) // 600m

the you make the call against the database

var queryHandle = query.observeEventType(.KeyEntered, withBlock: { (key: String!, location: CLLocation!) in
print("Key '\(key)' entered the search area and is at location '\(location)'")
})

Every Key that is returned will be the UserID for your datebase and you can access the relevant path through a /User/{UserID}/...

Get all objects within specific range in GeoFire

You can use the key entered events to first save all keys for a query in a dictionary and then use the ready event to determine when all keys have been added:

NSMutableDictionary *allKeys = [NSMutableDictionary dictionary];
[query observeEventType:GFEventTypeKeyEntered withBlock:^(NSString *key, CLLocation *location) {
[allKeys setObject:location forKey:key];
}];
[query observeReadyWithBlock:^{
// Create an immutable copy of the keys in the query
NSDictionary *valueData = [allKeys copy];
NSLog(@"All keys within a query: %@", valueData);
}];

Don't forget to clean up your listeners afterwards.

How can i get user nearby my location in geofire,Firebase

Keep your GeoFire Locations separate from everything with a key to reference the other additional data e.g. user info or post info. As mixing static and dynamic data would not be the most efficient way of storing the data.

See my data structure and query here:

Retrieving Keys From GeoFire within Radius in Swift

GeoFire observeReady gets executed prematurely in Swift

What you're seeing is expected behavior. The observeReady is guaranteed to fire after all the corresponding observe(.keyEntered) have been called. You can verify this with some simple logging statements:

query.observe(.keyEntered) { (key: String!, venueLocation: CLLocation!) in 
print(".keyEntered")
}
query.observeReady {
print(".observeReady")
}

When you run this it will print:

.keyEntered

.keyEntered

...

.observeReady

That is in line with how the API is supposed to work. But in the .keyEntered you are loading additional data from Firebase, which happens asynchronously. And those calls may indeed complete after the .observeReady has fired.

So you will need to implement the necessary synchronization yourself. A simple way to detect if you have loaded all the additional data, is to keep a count of all the keys for which you still need to load data. So you +1 that every time you add a key, and -1 every time you've loaded the venue data:

let venuesToLoadCount = 0
query.observe(.keyEntered) { (key: String!, venueLocation: CLLocation!) in
venuesToLoadCount = venuesToLoadCount + 1
self.REF_VENUES.child(key).observeSingleEvent(of: .value, with: { (snapshot) in
venuesToLoadCount = venuesToLoadCount - 1
if venuesToLoadCount == 0 {
print("All done")
}
}
}
query.observeReady {
if venuesToLoadCount == 0 {
print("All done")
}
}


Related Topics



Leave a reply



Submit