Firestore Geoquery

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] real-time geolocation is behind some of the most awesome apps in the world such as uber Instagram and ways to name a few but building these features from scratch requires a lot of complex math and advanced data modeling but fortunately there's tools we can use to build features like this without any trigonometry and we can do it in the next few minutes if you're new here like and subscribe and if you're serious about building apps like this consider becoming a pro member at angular firebase com our goal today is to use firestore and angular google maps to build a real-time geolocation feature so we'll be able to say give us all the documents that are within X kilometers of some center point and have that query update in real time but before we get going I have a couple examples of real-world angular firebase apps that use geolocation features the first one is cipher links which was built by an angular firebase Pro member and is essentially a LinkedIn for coders that allows you to find programmers geographically based on a filtered set of criteria and the next one is pod mapped word which is an open source project using angular and firebase that allows you to locate podcasts from around the world check out those links in the description but the next thing I want to talk about is how geo queries actually work because they're a lot different than a normal query that you would make in firestore so we create this fractal pattern where we have a grid of numbers and letters that segment the globe then we can build out a string value by repeating this pattern over and over again inside of each cell so every additional character in the string will be an additional level of precision for the location we're going to be saving our geohashes as 9 characters which is precise to about four and a half meters squared if you go to movable-type store you can explore the bounding boxes for different geohashes if we want to query firestore for all of the documents inside of a single geo hash it's actually pretty straightforward we can set the starting point as the Geo hash the endpoint as the hash plus a high Unicode character then we can order by the property it has that hash and then do start at end at but here's the problem let's imagine Kathy and Tim our next-door neighbor's and Tim does a search within this geo hash even though Kathy's right next door he's only going to get results inside of his geo hash so to get the true results you would have to get all of the neighboring geohashes as well and then draw a radius around them to find anything within that radius and there's a bunch of other little edge cases that you'll run into as well which is why I decided to just create a library that handles all this stuff under the hood it's called geo fire X and it uses rxjs and fire a store to make these queries possible but don't worry I didn't do any of the trigonometry myself I left all that to an awesome library called turf Jas and it's compatible with both flat earth and rounder theories it's also compatible with any JavaScript framework as long as it's using firebase in rxjs let's go ahead and get started from a brand new angular app and then the first thing we'll do is install the angular Google Maps package which is a great component library if using Google Maps from your firebase project you can go to the Google cloud platform console and enable the Google Maps JavaScript API from there we can install angular Google Maps in our app as well as firebase and geo fire X now at this point if you're using angular or ionic I would recommend using the angular fire to library but the bare minimum thing you need to do is just initialize a firebase app so that should look something like this code here then you'll also want to initialize angular Google Maps with your API key which you can do here in the app module now let's create a basic map with a GM which is super easy the first thing we want to do is go into our CSS and make sure we give it a width and height of something other than zero otherwise you won't be able to see the map at all after that we can just declare an AGM map component and give it a starting the latitude and longitude point we can also drop in a marker and give it a latitude and longitude as well and that will just pop up on the map at that point what we'll do next is loop over a collection of documents and firestore and render them on the map as these markers one of the special thing is that geo Firex does is that it saves data in a format that can be queried in order to make geo queries you need to have an object on the document that contains a geo hash and a geo point the library will format this for you automatically but you can save multiple geo points on a single document so you can do geo queries against multiple parameters so let's go ahead and make a query against this existing data set I'm going to go ahead and import geo Firex as well as our firebase app then we can initialize GFI rx by passing it a reference to our firebase app and then we'll also declare a property called points which is an observable of the actual documents that we query there are several variables that are needed to make a geo query the first one is your center point which can just be a latitude and longitude you can create a geo hash with the library by calling the point method it can do a bunch of other things like return geo JSON and calculate distance and bearing and things like that then the next variable that you'll need is the radius that you'll draw around the center point which will always be in kilometers under the hood the library uses Turf j s to calculate the haversine distance which also takes into account the curvature of the earth and lastly we need to specify the object that contains the geo data because remember a single document can have multiple geo points that can be queried against then the next thing we do is make a reference to the firestore collection this is just a wrapper for the main SDK that provides some additional functionality for geolocation to perform a geo query you can use though within method that we'll take in the center radius and field and that returns an observable that you can just subscribe to and it will stay in sync with any changes that happen in real time to that collection but because we're using rxjs we can do this in a little bit more of a dynamic way for example let's say the user clicks a button that will expand the radius to a different value for that we could set up the radius as a behavior subject which itself isn't observable that can happen new values push to it then we'll define our observable points as the radius behavior subject that has then switch mapped to the actual observable geo query and I would like to point out that within returns a hot observable that is cash to the last value that means you can have multiple subscribers to it and you will only be charged for the initial document read so by setting this up with a switch map we can now change the radius and get a whole new query each time the user clicks a button for example we just need to call radius next and everything else will change reactively now we need to unwrap the observable of our locations in angular we can do this very conveniently with the async pipe but in other frameworks you'd want to call subscribe on the observable and handle it accordingly inside of our AGM marker we'll do an ng for loop and we'll loop over each point of points using the async pipe to unwrap it because it returns an observable array of document data this gives us access to all of the data on each document but it also returns some additional metadata that's specifically designed for building real-time map features for example it returns the distance and bearing that this document was found at relative to the query center point which can only be figured out at runtime you might query a collection of restaurants that are relative to a user's current GPS position on their phone and the query metadata gives you the information needed to show the distance to that point to the user in the UI and that will be by default on the query metadata on the return points I have a premade demo that I'd use for integration testing and every point in the document is a specific distance and bearing from the center and the actual gray circle is the radius of the query and if we click on any of these points we'll also see that query metadata which again is the distance and bearing what's really cool that fire store is everything is just real time by default so imagine we have one of these documents that are being written to every couple of seconds as the users position moves it will update in the UI like we see happening here with the blue marker but as soon as it falls out of range it disappears from the query and also the UI there's a bunch of other little features that I've added to geo by rx specifically for working with tools like map box and Google Maps if you find it useful make sure to star it and please report any issues that you encounter when using it I'm gonna go ahead and wrap things up there thanks so much for watching and I'll talk to you soon [Music]
Info
Channel: Fireship
Views: 43,720
Rating: undefined out of 5
Keywords: firebase, webdev, app development, typescript, javascript, lesson, tutorial, firestore, firestore geoquery, firebase geoquery, geofirex, geofire, geofirestore, firestore geolocation, geopoint, geosearch, rxjs, rxjs 6, geohash, geographic database, firebase map
Id: lO1S-FAcZU8
Channel Id: undefined
Length: 8min 26sec (506 seconds)
Published: Wed Jul 11 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.