Update (June 23, 2014): This post is about GeoFire 1.0. We have since released GeoFire 2.0 which can be read about in a blog post here.
Location based services are hot. From a black car to the best sushi near you, your favorite apps use location tracking and localized search to bring the (relevant) world to your fingertips. Today we’re excited to release GeoFire - a geospatial library for Firebase that makes it easy for you to add real-time, location-based features to your app; with just a few GeoFire function calls, you can leverage your users’ locations too.
The What
Imagine you want to build an app to monitor airplanes in and around the San Francisco airport - the app finds planes entering and leaving the airport’s airspace, which is defined by a preset radius around the control tower, and keeps track of all planes that are within the airspace.
The app needs two location-based features:
Localized search, to find planes that are located within the preset radius from the tower. As planes enter and leave the airspace, the search results must change too. Real-time location tracking, to ensure plane locations in the app are up-to-date.
Implementing these features using just Firebase is non-trivial: you have to store the planes’ locations, represented as latitude-longitude pairs, implement distance calculation with latitude-longitude pairs, implement efficient location modification and re-calculation of distances, …and ten other things you’d rather not; so we built GeoFire for you.
The How
The GeoFire library provides functions to store data that you’d like to query by location, update location data, and perform location based searches that reflect location updates in real-time.
With Firebase and GeoFire, all you need to do to build the control tower app is:
Call GeoFire’s insertByLocWithId function to store the planes’ initial locations to Firebase. Call the updateLocForId function to update the planes’ locations as they move. Call the onPointsNearLoc function with the tower’s location and airspace radius to get the set of planes within the airspace. Any changes to the set are automatically reported in real-time, so the function need only be called once.
insertByLocWithId
updateLocForId
onPointsNearLoc
And that’s it, you’re done. Yup, that’s what we said - location-based anything is easy with GeoFire.
The But Really How
To store data by location in Firebase, GeoFire converts the latitude-longitude pair to a geohash. A geohash is an alphanumeric string which is generated by interleaving the bit representations of the latitude and the longitude coordinates of a location, and base32-encoding the result. Geohashes have a neat property that makes them suitable for geospatial queries like localized search: points with similar geohashes are guaranteed to be near each other. (It's worth noting that points that are near each other may not have similar geohashes though.)
The data for location querying is stored at its geohash in Firebase. To search for the nearest data points to a given location, GeoFire executes a series of a prefix queries over the geohashes; the set of prefixes queried depends on the search radius and the zoom resolution. This blog post provides a good introduction to the terminology and geohashing.
For location queries by client-provided id, GeoFire also inserts data at its id in Firebase. A simple double look-up or look-up+operation is all that’s needed to support the x-by-Id functions then.
The Fun and Profit
GeoFire makes it delightfully easy for you to add location-based features to your app. So go forth, treat your users to some of that localized love we all love!
As always, we’re all ears for feedback, comments and questions - reach out to us via the Firebase google group or Twitter!