为什么 GeoFire 查询有时会使用以前加载的数据?

Why does a GeoFire query sometimes use data from a previous load?

所以有时进入搜索半径的人是以前的,即有人在搜索半径内,但根据数据库中的当前数据不在半径内。其他时候,以前不在搜索范围内但现在在搜索范围内的人不会被打印出来。

这每次只会发生一次,即如果我在错误包含或排除后第二次加载应用程序,则会打印正确的数组。

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let databaseRef = Database.database().reference()
    guard let uid = Auth.auth().currentUser?.uid else { return }
    guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
    print("locations = \(locValue.latitude) \(locValue.longitude)")
    latestLocation = ["latitude" : locValue.latitude, "longitude" : locValue.longitude]
    let lat = locValue.latitude
    let lon = locValue.longitude
    dict = CLLocation(latitude: lat, longitude: lon)
    print("dict", dict)

    if let locationDictionary = latestLocation {
        databaseRef.child("people").child(uid).child("Coordinates").setValue(locationDictionary)
        let geofireRef = Database.database().reference().child("Loc")
        let geoFire = GeoFire(firebaseRef: geofireRef)
        print(CLLocation(latitude: lat, longitude: lon),"GGG")
        geoFire.setLocation(CLLocation(latitude: lat, longitude: lon), forKey: uid)
    }

    manager.stopUpdatingLocation()

    }

Override func ViewdidLoad() {
    super.viewDidLoad()

    guard let uid = Auth.auth().currentUser?.uid else { return }
    let geofireRef = Database.database().reference().child("Loc")
    let geoFire = GeoFire(firebaseRef: geofireRef)
    geoFire.getLocationForKey(uid) { (location, error) in
        if (error != nil) {
            print("An error occurred getting the location for \"Coordinates\": \(String(describing: error?.localizedDescription))")
        } else if (location != nil) {
            print("Location for \"Coordinates\" is [\(location?.coordinate.latitude), \(String(describing: location?.coordinate.longitude))]")
        } else {
            print("GeoFire does not contain a location for \"Coordinates\"")
        }
    }

    let query1 = geoFire.query(at: self.dict, withRadius: 3)
    query1.observe(.keyEntered, with: { key, location in
        print("Key: " + key + "entered the search radius.") ///**this prints keys of users within 3 miles. This is where I see the wrong inclusions or exclusions**
        do {
            self.componentArray.append(key)
        }
            print(self.componentArray,"kr")
        }
    )
}

以下是我要进行的测试以及可能的解决方案。这与您的代码类似,但排除了一些未知数;我想我们也可能 运行 陷入异步问题,所以试一试。

在 viewDidLoad 中获取当前用户的位置。该位置将用作查询的中心点

self.geoFire.getLocationForKey(uid) { (location, error) in
    if (error != nil) {
        print("An error occurred getting the location for \"Coordinates\": \(String(describing: error?.localizedDescription))")

    } else if (location != nil) {
        self.setupCircleQueryWith(center: location) //pass the known location

    } else {
        print("GeoFire does not contain a location for \"Coordinates\"")
    }
}

一旦 location 变量被填充到闭包中(所以你知道它是有效的)将它传递给函数以生成查询

func setupCircleQueryWith(center: CLLLocation) {
    var circleQuery = self.geoFire.queryAtLocation(center, withRadius: 3.0)

    self.queryHandle = self.circleQuery.observe(.keyEntered, with: { key, location in
      print("Key '\(key)' entered the search area and is at location '\(location)'")
      self.myKeyArray.append(key)
    })
}

self.queryHandle 是一个 class 变量,我们以后可以用它来删除查询。我还将 self.geoFire 设置为指向 Loc.

的 class 变量

编辑

在 class 的最顶部,添加一个 class 变量来存储密钥

class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
    
    var ref: DatabaseReference!
    var myKeyArray = [String]()
    let queryHandle: DatabaseHandle!

并记住还要添加一个 .keyExited 事件,这样当键退出该区域时,您就会知道何时从数组中删除键。