Ever wondered how delivery and ride-hailing apps know where you are at a given point in time? The answer is geolocation.
In this tutorial, we’ll show you how to implement geolocation in React Native. We’ll build an example app in React Native that displays the user’s location on a map in longitude and latitude coordinates and enables the user to send their location to another source, such as Twitter.
We’ll cover the following:
- What is geolocation?
- Geolocation in React Native
- Initialize a React Native project
- Required dependencies for geolocation in React Native (iOS and Android)
- Adding geolocation to a React Native app
- Importing
react-native-library
RNLocation.configure
- Requesting permission to access location data
- Getting the user’s location data
- Sending location data in React Native
- Sending user location data to Twitter
What is geolocation?
Geolocation is the ability to deduce the geographic position of a device that is connected to the internet. Most often, the user must grant permission for an app to access their location data.
One simple example of geolocation is using a device’s IP address to determine the country, city, or postal code at which it is located.
Geolocation in React Native
React Native has an API for geolocation: @react-native-community/geolocation
. However, Google does not recommend using the React Native API for geolocation because it is less accurate and slower than the recommended Google Location Services API.
Thankfully, the React Native community has developed two excellent libraries for implementing geolocation in React Native:
In this React Native geolocation tutorial, we’ll use the react-native-location library
. It is available as a Node package and thus available on npm.
We’ll build an app that does the following:
- Asks permission to access location data on your Android and iOS device
- Picks your location coordinates
- Saves or sends your location coordinates
It is recommended to use Node version 10+. To check your Node version:
$ node -v // returns node version
Note you can use nvm
to manage multiple node versions installed on your machine.
React Native has a built-in command-line interface that you can use to generate a new project. You can access it without installing anything globally using npx, which ships with Node.js.
Initialize a React Native project
To begin our project, run the following command in the terminal:
$ npx react-native init ReactNativeGeolocation
npx
is a Node-based command that can be used to run Node-based dependencies in a terminal without having to install such dependencies on your machine.
The init
part of the command is the instruction to initialize a new React Native project with ReactNativeLocation
as the directory where the project files will be installed.
The npx react-native
command works without having to install React Native on your machine. Alternatively, you can install React Native globally on your machine to run React Native commands without using npx
.
To install React Native globally, run the following command:
$ npm install -g react-native-cli
You can then check React Native is installed using:
$ react-native -v
This prints the React Native version installed on your machine to the console.
Open up your favorite IDE and go to the ReactNativeGeolocation
directory. The command we ran to initialize the project set up the React Native app for us.
We’ll write all our code in the App.js
file. Make sure you’re in the root directory of your app to run the commands.
The first step is to start Metro. Metro is a JavaScript bundler that ships with React Native. Metro “takes in an entry file and various options, and returns a single JavaScript file that includes all your code and its dependencies.”
$ npx react-native start
With Metro running in a terminal, open another terminal and run:
$ npx react-native run-android
Have an Android emulator running or a mobile device connected to your PC in debug mode to run the app on your mobile device. You should then see the following screen:
Now we can go on to App.js
and start making changes to the app.
Remove all the old code in App.js
and replace it with this:
/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow strict-local */ import React from 'react'; import {StyleSheet, View, Text} from 'react-native'; const App = () => { return ( <View style={styles.container}> <Text>Welcome!</Text> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, }); export default App;
This gives us a new screen where we continue writing our program.
Required dependencies for geolocation in React Native
Install the library using either Yarn:
$ yarn add react-native-location
Or npm:
$ npm install --save react-native-location
Using this npm package requires further installation instructions for iOS and Android Devices.
iOS
You can link the library using Cocoapods by adding this line to your podfile:
$ pod 'react-native-location', :path => '../node_modules/react-native-location/react-native-location.podspec'
You then need to make sure you have the correct usage descriptions inside your Info.plist
file. The message will show in the alert box when your app requests permissions and lets the user know why you are asking for that permission. They are also part of the app store review process.
If you’re only requesting location access when the app is in use, you just need to make sure you have the NSLocationWhenInUseUsageDescription
item in your Plist
. If you’re requesting background permission, you’ll also need to add NSLocationAlwaysAndWhenInUseUsageDescription
and NSLocationAlwaysUsageDescription
to your PList
file.
The easiest way to add these is to find your Info.plist
. Open your favorite IDE and find the file in your project source directory. You can then enter the following items into the file:
<key>NSLocationWhenInUseUsageDescription</key> <string>This is the plist item for NSLocationWhenInUseUsageDescription</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>This is the plist item for NSLocationAlwaysAndWhenInUseUsageDescription</string> <key>NSLocationAlwaysUsageDescription</key> <string>This is the plist item for NSLocationAlwaysUsageDescription</string>
Android
Automatically link the library using the CLI tool. The easiest way to link the library using the CLI tool is to run this command from the root of your project:
$ react-native link react-native-location
To activate Android manifest permissions, go to android >> app >> src >> main >> AndroidManifest.xml
and add the following permissions to your AndroidManifest.xml
:
<uses-permission android:name="android.permission.ACCESSCOARSELOCATION"/>
If you want to access fine location, you should also include:
<uses-permission android:name="android.permission.ACCESSFINELOCATION"/>
The next step is to install the Google Fused Location provider dependency, which is optional. The library provides two methods of getting the location on Android. The default is the built-in location manager. However, you can optionally choose to install the Fused Location library, which provides more accurate and faster results. The downside is that it will only work on devices with Google Play Services installed and configured (which is most Android devices in the west, but not Kindle devices or Asian markets).
If you would like to use the Google Play Services Fused Location provider, you need to add these dependencies to your android/app/build.gradle file:
implementation "com.google.android.gms:play-services-base:16.0.1" implementation "com.google.android.gms:play-services-location:16.0.0"
Principally, we’ll get permission from the user to access their location. We’ll then get the user’s coordinates and send these coordinates.
Adding geolocation to a React Native app
Let’s add two separate buttons to our React Native app: one to get the user’s location, which we’ll then store in the app state, and another to send the user’s location to Twitter.
Add two buttons to App.js
under the welcome text:
<View style={{marginTop: 10, padding: 10, borderRadius: 10, width: '40%'}}> <Button title="Get Location" /> </View> <Text>Latitude: </Text> <Text>Longitude: </Text> <View style={{marginTop: 10, padding: 10, borderRadius: 10, width: '40%'}}> <Button title="Send Location" /> </View>
Our app now looks like this:
Importing react-native-library
Once we have the react-native-location
library installed, we can implement the logic to get the latitude and longitude coordinates. Using ES6, we’ll write an async request that will be handled by the event on the button: onPress
, which is triggered by the “GET LOCATION” button.
Once this event handler is triggered, the user is asked for permission to access their location, upon granting the request, the location will be returned to the user.
First, import react-native-library
and call the configure method on it:
import RNLocation from 'react-native-location'; RNLocation.configure({ distanceFilter: null })
RNLocation.configure
This method takes the one object, distanceFilter
. The distanceFilter
is the minimum distance in meters that a device location will change before the new location update callback in the sample app is called. It is set to null
so as to change whenever you move your device.
Update the “GET LOCATION” button as follows:
<Button title="Get Location" onPress={permissionHandle} />
Requesting permission to access location data
onPress
is an event handler that calls the function permissionHandle
. Let’s go ahead and write the logic for the named function permissionHandle
.
const permissionHandle = async () => { console.log('here') let permission = await RNLocation.checkPermission({ ios: 'whenInUse', // or 'always' android: { detail: 'coarse' // or 'fine' } }); console.log('here2') console.log(permission) }
The console.log
statements are to check that we can access function calls. The console log on the permission will return false
. The checkPermission
method is used to check whether the user has granted permission to look up their device location via the app. It is useful to call checkPermission
before requestPermission
to confirm that the user has granted the required permission status.
This is why it is false
, since the permission has not been requested from the user. To get permission from the user, we’ll use the requestPermission
method.
permission = await RNLocation.requestPermission({ ios: "whenInUse", android: { detail: "coarse", rationale: { title: "We need to access your location", message: "We use your location to show where you are on the map", buttonPositive: "OK", buttonNegative: "Cancel" } } }) console.log(permission)
The requestPermission
method must be called before subscribing to location updates. The requestPermission
method takes the platform type as object keys, which are iOS
and Android
. The Android
object has an internal rational object, which is displayed when the user is asked for permission a second time. requestPermission
returns a promise that resolves to TRUE
if permission was granted or FALSE
if it was not granted.
When the user grants permission, TRUE
is logged to the console. When the user denies permission, FALSE
is logged to the console. On clicking the button again, the rational object is parsed on the user before the request permission screen comes back up.
Here is the screen when the user clicks the button again after denying permission:
Getting the user’s location data
When the user then grants permission, we have to update the code to get the user’s location:
let location; if(!permission) { permission = await RNLocation.requestPermission({ ios: "whenInUse", android: { detail: "coarse", rationale: { title: "We need to access your location", message: "We use your location to show where you are on the map", buttonPositive: "OK", buttonNegative: "Cancel" } } }) console.log(permission) location = await RNLocation.getLatestLocation({timeout: 100}) console.log(location, location.longitude, location.latitude, location.timestamp) } else { console.log("Here 7") location = await RNLocation.getLatestLocation({timeout: 100}) console.log(location, location.longitude, location.latitude, location.timestamp) }
Let’s break down the code:
- First, a
location
variable is declared (not assigned at this time) using theLet
keyword so that it can be reassigned at some other time - Next, we checked the permission status granted by the device. This is obtained using the
requestPermission
method to ask the user to grant permission to the app. This logic is implemented in the first section of theIF
construct IF
the permission is obtained from the user, using thegetLatestLocation
method, log the location to the console to ensure that you can see the app working at this point- The
ELSE
part returns thegetLatestLocation
method, so long as permission was granted prior - The
getLatestLocation
method will time out if the promise is not resolved in the time parsed in
The location object is logged to the console with the following example information in JSON format:
{ "accuracy": 2000, "altitude": 0, "altitudeAccuracy": 0, "course": 0, "courseAccuracy": 0, "fromMockProvider": false, "latitude": 37.42342342342342, "longitude": -122.08395287867832, "speed": 0, "speedAccuracy": 0, "timestamp": 1606414495665 }
What we need from the object response is the latitude and longitude, which we then log to the console as well.
There, we can get the user’s location.
Sending geolocation data in React Native
To send the user’s goelocation data to Twitter, we need to simply turn the “SEND LOCATION” button into a “Tweet” button.
Before we send the location to the User, it is fair to display the data returned in the example. To do this we add the useState Hook from React to our app:
import React, { useState } from 'react';
Then we define a state inside our App function:
[viewLocation, isViewLocation] = useState([])
We update the if statement to call the isViewLocation method and update the viewLocation array with the Location information object returned:
isViewLocation(location)
To view the information returned, update the Location
and Longitude
text tags:
<Text>Latitude: {viewLocation.latitude} </Text> <Text>Longitude: {viewLocation.longitude} </Text>
viewLocation.latitude
returns the latitude in the object response called by the method isViewLocation
. Same goes for the longitude.
At this point, we can update the button to send the user’s location to Twitter.
Here’s a view of our final example app:
Sending user location data to Twitter
We have to initialize a state that takes the location when it is returned and set it to a content to be tweeted:
const [tweet, setTweet] = useState([viewLocation.longitude, viewLocation.latitude]);
The “SEND LOCATION” button will take an event handler that will trigger a function call.
Update the button like so:
<Button title="Send Location" onPress={tweetLocation} />
We can go ahead and write the function:
const tweetLocation = () => { let twitterParams = []; try { if (tweet) twitterParams.push(${tweet}); const url = 'https://twitter.com/intent/tweet?' + twitterParams.join('&'); Linking.openURL(url) } catch (error) { console.log(error); } }
The function is a simple script that sets an empty array, twitterParams
. The conditional if
statement is parsed in a try catch
block, in which the console logs an error if any in the catch block. The conditional if
pushes a tweet to the twitterParams
empty array and, using the React Native Linking component, opens up the URL with the openURL
method.
Add the setTweetContent
method to the getLocation
function:
setTweetContent([viewLocation.longitude, viewLocation.latitude])
Now you can tweet your location coordinates.
Conclusion
There’s a lot more you can do now that you know how to acquire a user’s location. You can build a delivery service, track a user, and even build an emergency button alert system. The possibilities are endless!
You can access the full source code for this project on GitHub.
LogRocket: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
Try it for free.
Hello Emmanuel, just to help the other people going through this article. I noticed a small ‘possible modification’.
When you mention the “getLocation” function in the finishing paragraph I found myself in a state of minute confusion. After checking the source code it makes sense that you have replaced that function with “permissionHandle”
Thank you for reading the article Mushtaq! I do hope you found it useful. Thank you much more for pointing that out.
So cool! I had no idea you could build an emergency button feature. This is super useful. Thank you so much for sharing.