senty senty - 6 months ago 405
Swift Question

Retrieving Location Data with Radius using Firebase & GeoFire

I am trying to use GeoFire to retrieve and according to radius (for example, everything in 10km distance).

To remain clear, I am saving the details and location separately in the database, so details' id is same with locations' id. While saving the data, I use:

var details = ["a":"a", "b":"b", etc]
let checkpointRef = eventRef.childByAutoId()
checkpointRef.setValue(details)
let checkpointId = checkpointRef.key

let geofireRef = ref.childByAppendingPath("checkpointLocations")
let geoFire = GeoFire(firebaseRef: geofireRef)

geoFire.setLocation(CLLocation(latitude: usersLatitude, longitude: userLongitude), forKey: checkpointId) {...


Until here, everything seems fine in database.




While retrieving data, after getting user's latitude and longitude from core location, I am trying to :

func retrieve() {
let geofireRef = Firebase(url: self.baseurl + "/checkpointLocations")
let geoFire = GeoFire(firebaseRef: geofireRef)

let center = CLLocation(latitude: usersLatitude, longitude: usersLongitude)

var circleQuery = geoFire.queryAtLocation(center, withRadius: 10)

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


First problem arises here with
observeEventType()
. I don't want to observe event continuously. Instead, like a classic TableView, I want to retrieve the data once and display, and re-retrieve data with "pull to refresh" functionality. My first question is, are there any function for GeoFire to work as
observeSingleEventOfType
of Firebase and retrieve data once?




Secondly, this function is printing this warning couple of times:


[Firebase] Using an unspecified index. Consider adding ".indexOn": "g" at /checkpointLocations to your security rules for better performance


..but doesn't log anything else. I don't think it goes inside the function because it doesn't print the
print("Key..
part. It doesn't also
print("A")
.

I thought it might be caused because of the 'Firebase Rules'. Using this answer on SO, I tried adding this:

"rules": {
"checkpointLocations": {
"$key": {
".read": true,
".write": true,
"geofire": {
".indexOn": "g"
}
}
}
}


and also this:

"rules": {
"checkpointLocations": {
".read": true,
".write": true,
"geofire": {
".indexOn": "g"
}
}
}


But neither works.

Update:

Using @Gregg's answer, I fixed the warnings, however, it still doesn't go inside the closure.

Answer

Dont have enough points for commenting but move the ".indexOn" up to the checkpointLocations node. Currently you have it on checkpointLocations/geofire. For example:

"rules": {
    "checkpointLocations": {
      ".read": true,
      ".write": true,
      ".indexOn": "g"
      "geofire": {

      }
    }
  }