SwiftUI GeoQuery returning no documents from Firestore despite matching geohash

40 Views Asked by At

My code is setting geohashes on venues saved to Firebase Firestore as follows:

static func generateGeoHash(latitude: Double, longitude: Double) -> String {
    let location = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    return GFUtils.geoHash(forLocation: location)
}

These are being saving in Firestore as expected: geoHash "gcpvhfh0cv"

For querying the database to get back the venues in the current region, I've followed guidance from the Firestore docs and this thread for implementing the callback competion: How to get Documents out of an geo query?

The resulting function is:

func queryVenuesForRegion(userRegion: MKCoordinateRegion, completion: @escaping ([Venue]) -> Void) {
        
    //Get a reference to the database
    let db = Firestore.firestore()
    
    let centerCoordinate = userRegion.center
    let radiusInMeters: Double = 50 * 1000 //max(userRegion.span.latitudeDelta, userRegion.span.longitudeDelta) * 5000 // Approximate conversion, adjust as needed

    // Calculate the query bounds using GeoFire utility function
    let queryBounds = GFUtils.queryBounds(forLocation: centerCoordinate, withRadius: radiusInMeters)

    // Create a query to retrieve venues within the region
    let queries = queryBounds.map { bound -> Query in
        return db.collection("venues")
            .order(by: "geoHash")
            .start(at: [bound.startValue])
            .end(at: [bound.endValue])
    }
    
    // Create a dispatch group outside of the query loop since each iteration of the loop
        // performs an asynchronous task.
        let dispatch = DispatchGroup()
    
    var matchingDocs = [QueryDocumentSnapshot]()
    
    // Collect all the query results together in a sinlge list
    func getDocumentsCompletion(snapshot: QuerySnapshot?, error: Error?) {
        guard let documents = snapshot?.documents else {
            print("Unable to fetch snapshot data. \(String(describing: error))")
            completion([])
            dispatch.leave() // leave the dispatch group when we exit this completion
            return
        }
        

        for document in documents {
                let lat = document.data()["latitute"] as? Double ?? 0
                let lng = document.data()["longitude"] as? Double ?? 0
                let coordinates = CLLocation(latitude: lat, longitude: lng)
                let centerPoint = CLLocation(latitude: centerCoordinate.latitude, longitude: centerCoordinate.longitude)

                // We have to filter out a few false positives due to GeoHash accuracy, but
                // most will match
                let distance = GFUtils.distance(from: centerPoint, to: coordinates)
                if distance <= radiusInMeters {
                    matchingDocs.append(document)
                }
            }
        dispatch.leave() // leave the dispatch group when we exit this completion
    }
    
    // After all callbacks have executed, matchingDocs contains the result. Note that this
    // sample does not demonstrate how to wait on all callbacks to complete.
    for query in queries {
        dispatch.enter() // enter the dispatch group on each iteration
        query.getDocuments(completion: getDocumentsCompletion)
    }
        // [END fs_geo_query_hashes]
    
    var venues = [Venue]()
    
    dispatch.notify(queue: .main) {
        for document in matchingDocs {
            if let venue = try? document.data(as: Venue.self) {
                venues.append(venue)
            }
        }
    }
    
    // Call the completion handler with the parsed venues
        completion(venues)
}

The code is being called and the regions line up (long and lat both for eg central london).

queryBounds and queries have data, but documents and matchingDocs always remain empty.

Retrieving all docs from the database successes and map annotation as applied.

Trying to debug for ages but with no luck. Driving me bonkers. Any ideas welcome.

0

There are 0 best solutions below