javascriptfirebasegoogle-cloud-firestoregeopointsgeofirestore

How to query all geoqueries in a set radius with geofirestore?


I am trying to make a query to a cloud-firestore which should return all geopoints within a radius of, say, 10.5 km of a given geopoint. I am trying to use geofirestore to achieve this. I have tried using geoqueries, but i can't find a method or property which returns this. My question seems as if it has a fairly simple answer, but I am new to both firebase and geofirestore. Thank you.

My code so far:

document.addEventListener('DOMContentLoaded', () => {
    const app = firebase.app();
});

var db = firebase.firestore();

db.settings({
    timestampsInSnapshots: true
});

const collectionRef = firebase.firestore().collection('geofirestore');

// Create a GeoFirestore index
const geoFirestore = new GeoFirestore(collectionRef);

const post1 =  db.collection('posts').doc('firstpost');

const test = {lat: 39.369048, long: -76.68229}

const geoQuery = geoFirestore.query({
    center: new firebase.firestore.GeoPoint(10.38, 2.41),
    radius: 10.5,
    query: (ref) => ref.where('d.count', '==', '1')
});

console.log(geoQuery.query());

Solution

  • I think the documentation may not be clear, but here's what is going on.

    The below code creates a GeoFirestoreQuery:

    const geoQuery = geoFirestore.query({
        center: new firebase.firestore.GeoPoint(10.38, 2.41),
        radius: 10.5,
        query: (ref) => ref.where('d.count', '==', '1')
    });
    

    If you wanted to make a geoquery you'd use the on listener for the key_entered event which will return documents in your query, see here.

    However you're calling the query function, which returns a Firestore Query, or CollectionReference (depending on if you passed in a query function when you created or updated the query criteria).

    Calling get on this query BYPASSES all of the GeoFirestore magic goodness, and would not provide you with what you want or expect... Instead you'd want to do something like this.

    // Store all results from geoqueries here
    let results = [];
    
    // Create geoquery
    const geoQuery = geoFirestore.query({
        center: new firebase.firestore.GeoPoint(10.38, 2.41),
        radius: 10.5,
        query: (ref) => ref.where('d.count', '==', '1')
    });
    
    // Remove documents when they fall out of the query
    geoQuery.on('key_exited', ($key) => {
      const index = results.findIndex((place) => place.$key === $key);
      if (index >= 0) results.splice(index, 1);
    });
    
    // As documents come in, add the $key/id to them and push them into our results
    geoQuery.on('key_entered', ($key, result) => {
      result.$key = $key;
      results.push(result);
    });