A complete guide to recording location data in React Native
Let’s say you’re starting your next project, and your app is location based. Which means you have to record your user’s location and display it on the map. At OK GROW! we use React Native which equips you with various libraries for doing so, without having to write any native code. But how exactly do you go about gathering users’ location data and displaying their location on a map? Here’s a quick guide to help you do all of this in React Native.
This is part one of a two-part series.
- In this post we will look at the options available for recording. We will look at pure React Native, Expo, and and the react-native-background-geolocation package as three approaches for gathering users’ location data.
- In Part 2 we discuss displaying the user’s location on a map in a React Native app and strategies for reducing noise in the recorded data to make the lines on the map look smoother. We will explore Google’s Snap to Road API, and The Kalman Filter as potential solutions.
Part 1 - Recording users’ location data
Below we introduce three approaches that allow you to poll for current location or listen for changes.
1 - Pure React Native
The easiest approach is to use React Native’s own API for receiving location. This API is an extension of the web spec. This approach does not permit a lot of customization in terms of the desired accuracy. It also does not provide information about the provider (e.g. Wifi, GPS, Antenna). Compared to the other two options, documentation is very limited and it’s lacking examples.
- No setup, no external libraries
- Does not work in the background
- Minimal functionality for advanced use
- Minimal documentation by Facebook with no examples: http://facebook.github.io/react-native/docs/geolocation.html
2 - Using Expo
One of the many APIs that Expo provides is Location. Note that Expo wraps React Native’s Location API and adds extra features to it. The extra features include geocoding and reverse geocoding (i.e. converting a GPS coordinate to a postal address). Another feature is the ability check status of location providers (i.e. whether or not location services is on or off). Unlike the Pure React Native approach, Expo’s API also allows you to ask for high accuracy location.
Another strong point is that Expo provides a thorough documentation, along with an example that you can run and modify right in the browser. This is all thanks to Snack, which allows you to run Expo apps in the browser.
Note that Expo is also working on making this API even better by adding the ability to record the user’s location offline. You can follow the progress of that here.
- 💯 Documentation with in-browser runnable examples
- Extra features such as reverse geolocating
- No extra setup if you already have Expo
- Has APIs for checking provider status and asking for permissions
- Does not work in the background
3 - Using react-native-background-geolocation
The options above should work for most of the interactions with Location. But if you are looking for something with more advanced features check the react-native-background-geolocation package.
This package allows you to specify your desired accuracy from 0 to 1000 meters, which correlates negatively with battery consumption. You can also customize how often location is tracked, based on the distance travelled, information from the movement sensors, and if they enter or exit a specified geofence.
It’s also pretty incredible that this package allows integration with SQLite, which allows you to store the recorded locations on the phone and also sync them to your database via HTTP.
HACK: You can use this package as a hack to make other packages with features such as recording audio and capturing camera pictures to function when your app is in the background. This is obviously not the intent of the package creator and therefore may not work for some specific cases. For more information, you can check the heartbeat function as well, which allows you to run specific tasks on an interval when the app is in the background.
Although this package is free for iOS, it costs $300 to purchase a license for it on Android for 1 app, and you also get support via Github issues from the package creator and maintainer. You can pay up to $749 to get more immediate support via Slack and licenses for 100 apps. Each of the plans above also gives you one year access to the private repo, which is a step more updated than the publicly accessible repo.
One downside of this approach is that you are using a package. If it’s not obvious to you why adding a package to a React Native app is a technical risk:
- Works in the background
- Ability to configure battery consumption and accuracy
- Event listeners for movement sensors and change in location provider
- SQLite integration on the phone, and syncing via HTTP
- Author maintains the package daily and provides support through Github and Slack
- Costs at least $300 for Android license
- Needs to be linked to your project and maintained over time
4 - Other options
There is also the following package which is free, but I have not tried it:
All options mentioned above are all worth using, depending on the needs of the application. If you are already using Expo, using Expo’s API you can access a lot of features without any extra libraries. Otherwise, you might want to start by using the pure React Native solution until you need more advanced features like logging in the background.
In Part 2 we cover displaying and normalizing the data.