簡體   English   中英

SwiftUI 中具有實時更新結果的 Firestore Geohash 查詢

[英]Firestore Geohash Query with Live Updating Results in SwiftUI

我正在嘗試在 SwiftUI 中構建一個 iOS 應用程序,用戶可以在其中找到靠近其當前位置的“帖子”。 我有一個名為 Posts 的子集合,帶有 geohash。 有點煩人的是,谷歌的這個庫已無緣無故地存檔https://github.com/firebase/geofire-objc 相反,我不得不使用這個庫https://github.com/emilioschepis/swift-geohash

我找到當前用戶周圍的所有相鄰 geohashes,然后針對每個以 geohash 開頭並以 geohash + '~' 結尾的 geohash 運行針對 firstore 的查詢。 這是我寫的 function:

// import https://github.com/emilioschepis/swift-geohash

class FirestorePosts: ObservableObject {
    
    @Published var items = [FirestorePost]() // Reference to our Model
      
    func geoPointQuery(tag:String){
        do {
            let db = Firestore.firestore().collection("tags")
            let docRef = db.document(tag).collection("posts")
            // users current location is "gcpu"
            let neighbors = try Geohash.neighbors(of: "gcpu", includingCenter: true)
            let queries = neighbors.map { bound -> Query in
                let end = "\(bound)~"
                return docRef
                    .order(by: "geohash")
                    .start(at: [bound])
                    .end(at: [end])
            }
            
            func getDocumentsCompletion(snapshot: QuerySnapshot?, error: Error?) -> () {
                guard let documents = snapshot?.documents else {
                    print("Unable to fetch snapshot data. \(String(describing: error))")
                    return
                }

                self.items += documents.compactMap { queryDocumentSnapshot -> FirestorePost? in
                    return try? queryDocumentSnapshot.data(as: FirestorePost.self)
                }
            }

            for query in queries {
                print("ran geo query")
                query.getDocuments(completion: getDocumentsCompletion)
            }
        }
        catch{
            print(error.localizedDescription)
        }
    }
}

到目前為止,查詢有效並按預期返回項目。 但是,當 Firestore 發生變化時,結果不會實時更新。

  1. 我怎樣才能使這個查詢實時更新結果? 我嘗試添加query.addSnapshotListener ,但它不喜歡“完成:”參數
  2. 如何確保在返回結果之前完成所有查詢

您正在調用query.getDocuments ,它 獲取數據一次 如果您還想獲取該數據的更新,您應該使用addSnapshotListener ,它會在獲取初始文檔后偵聽更新

為確保所有查詢都已完成,您可以保留一個簡單的計數器,每次調用addSnapshotListener回調時都會增加該計數器。 當計數器等於查詢次數時,所有的查詢都得到了服務器的響應。 這正是實時數據庫的geofire-*庫為其onReady事件所做的。

我對此進行了重構,它似乎可以實時工作和更新。 我不需要使用計數器,因為我將文檔附加到self.items (雖然不確定那是否正確)。

...
for query in queries {
    query.addSnapshotListener { (querySnapshot, error) in
        guard let documents = querySnapshot?.documents else {
            print("No documents")
            return
        }
        
        self.items += documents.compactMap { queryDocumentSnapshot -> FirestorePost? in
            return try? queryDocumentSnapshot.data(as: FirestorePost.self)
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM