Search code examples
node.jsfirebasegeofire

Query Location by Radius with GeoFire


I know this is a basic question, but I’m having a lot of trouble with it nonetheless.

I have a Firebase database storing community events. Each event node has a geo location node (created with GeoFire) called eventPlace (see screenshot below).

Using GeoFire (and javascript), how would I query the entire database and get all events within a certain location/radius? Is this possible, given the way the data is stored? Or do I need to move all the location nodes to a common node (eventPlaces??) and query that single parent node?

Note that I am not seeking real-time data. These locations are stored previously and don’t change very often.

Thanks in advance…

enter image description here


Solution

  • As it stands right now geofire sort of serves as an index to make geoqueries on, and provides the key of the document you want (which would be stored in a separate "collection").

    You should be using geofire and a separate "collection" (call it eventPlaces)

    var firebaseRef = firebase.database().ref('eventPlaces');
    var geoFire = new GeoFire(firebaseRef);
    

    Now you can use it as an index for your events, and can add items to it like so.

    geoFire.set('-K_Pp-3RBJ58VkHGsL5P', [40.607765, -73.758949]);
    

    Your Firebase RTDB will look like this now:

    {
       'events': {
            '-K_Pp-3RBJ58VkHGsL5P': {
                // All your data here
            }
        },
       'eventPlaces': {
            '-K_Pp-3RBJ58VkHGsL5P': {
                'g': 'dr5x186m7u',
                'l': [40.607765, -73.758949]
            }
        }
    }
    

    So finally when you do a query on your geoFire:

    geoFire.query({
      center: [40.607765, -73.758949],
      radius: 10
    }).on('key_entered', (key, location, distance) => {
      console.log(key + ' entered query at ' + location + ' (' + distance + ' km from center)');
    });
    

    You'll end up being returned the key of the doc, for which you can do a normal Firebase query for that individual doc.