无法使用 Firebase (GeoFire) 和 Swift 靠近我所在位置的用户

Can't get near Users by my location with Firebase (GeoFire) and Swift

我想让所有用户都靠近我自己的位置。

我在位置管理器 didUpdateLocation 函数中编写了以下代码。

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)

然后我查询了我附近的所有用户。

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)'")
                
                
                
            })

如果我现在想用我的实际用户 (userdocid) 替换“test”,那是行不通的。

我如何抓住我的用户:

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

应用程序因空 NSArray 而崩溃。

提前致谢 马克

这个答案取决于您如何存储用户数据,但如果您将用户及其 documentId 作为用户 uid 存储,那么只需

let uid = Auth.auth().currentUser!.uid //should safe unwrap that optional

然后

geoFire.setLocation(CLLocation(..., forKey: uid)

然而,如果你想像你在问题中所做的那样得到它

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)
})

但同样,这有点多余,因为它表明将 uid 存储在 documentId 和子字段中,这是不必要的:

users
  uid_0 //the documentId
     name: "Users name"
     uid: "uid_0" //not needed

问题似乎实际上是获得中心点 - 例如如果它没有存储,那么当它被读取时,它将是空的,你会得到那个错误。

所以你必须先存储它

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!")
  }
}

一旦你成功地存储了一个中心点(你的位置),然后检索它,那么实际的查询应该是

let center = CLLocation(userLocation)
geoFire.queryAtLocation(center, withRadius: 20);

哦,很重要的一点是 setLocation 是异步的;服务器存储数据需要时间。你真的应该在闭包中处理数据

geoFire.setLocation(CLLocation(latitude: 37.7853889, longitude: -122.4056973), forKey: uid) { (error) in
   // data is now valid so perform your query
}