使用 Firebase 和 GeoFire 通过 Radius 检索位置数据
Retrieving Location Data with Radius using Firebase & GeoFire
我正在尝试使用 GeoFire 来检索并根据半径(例如,10 公里距离内的所有内容)。
为了保持清晰,我将详细信息和位置分别保存在数据库中,因此详细信息的 ID 与位置的 ID 相同。在保存数据时,我使用:
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) {...
到这里为止,数据库中的一切似乎都很好。
在检索数据时,从核心位置获取用户的经纬度后,我正在尝试:
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)'")
})
这里出现的第一个问题是 observeEventType()
。我不想连续观察事件。相反,就像经典的 TableView 一样,我想检索一次数据并显示,并使用 "pull to refresh" 功能重新检索数据。我的第一个问题是,GeoFire是否有任何功能可以作为Firebase的observeSingleEventOfType
并检索一次数据?
其次,此函数多次打印此警告:
[Firebase] Using an unspecified index. Consider adding ".indexOn": "g" at /checkpointLocations to your security rules for better performance
..但不记录任何其他内容。我不认为它进入函数内部,因为它不打印 print("Key..
部分。它也不 print("A")
.
我认为这可能是因为 'Firebase Rules' 引起的。在 SO 上使用这个 ,我尝试添加这个:
"rules": {
"checkpointLocations": {
"$key": {
".read": true,
".write": true,
"geofire": {
".indexOn": "g"
}
}
}
}
还有这个:
"rules": {
"checkpointLocations": {
".read": true,
".write": true,
"geofire": {
".indexOn": "g"
}
}
}
但都不起作用。
更新:
使用@Gregg 的回答,我修复了警告,但是,它仍然没有进入闭包。
评论点数不足,但将“.indexOn”移至 checkpointLocations 节点。目前您在 checkpointLocations/geofire 上拥有它。例如:
"rules": {
"checkpointLocations": {
".read": true,
".write": true,
".indexOn": "g"
"geofire": {
}
}
}
我正在尝试使用 GeoFire 来检索并根据半径(例如,10 公里距离内的所有内容)。
为了保持清晰,我将详细信息和位置分别保存在数据库中,因此详细信息的 ID 与位置的 ID 相同。在保存数据时,我使用:
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) {...
到这里为止,数据库中的一切似乎都很好。
在检索数据时,从核心位置获取用户的经纬度后,我正在尝试:
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)'")
})
这里出现的第一个问题是 observeEventType()
。我不想连续观察事件。相反,就像经典的 TableView 一样,我想检索一次数据并显示,并使用 "pull to refresh" 功能重新检索数据。我的第一个问题是,GeoFire是否有任何功能可以作为Firebase的observeSingleEventOfType
并检索一次数据?
其次,此函数多次打印此警告:
[Firebase] Using an unspecified index. Consider adding ".indexOn": "g" at /checkpointLocations to your security rules for better performance
..但不记录任何其他内容。我不认为它进入函数内部,因为它不打印 print("Key..
部分。它也不 print("A")
.
我认为这可能是因为 'Firebase Rules' 引起的。在 SO 上使用这个
"rules": {
"checkpointLocations": {
"$key": {
".read": true,
".write": true,
"geofire": {
".indexOn": "g"
}
}
}
}
还有这个:
"rules": {
"checkpointLocations": {
".read": true,
".write": true,
"geofire": {
".indexOn": "g"
}
}
}
但都不起作用。
更新:
使用@Gregg 的回答,我修复了警告,但是,它仍然没有进入闭包。
评论点数不足,但将“.indexOn”移至 checkpointLocations 节点。目前您在 checkpointLocations/geofire 上拥有它。例如:
"rules": {
"checkpointLocations": {
".read": true,
".write": true,
".indexOn": "g"
"geofire": {
}
}
}