Emmanuel Oaikhenan I started coding JavaScript in 2017 and delved into DevOps in 2019. In that time, I worked on projects that exposed me to learning more about software development and gained the requisite soft skills for communicating with teammates and clients.

React Native geolocation: A complete tutorial

8 min read 2488

React Native Geolocation Tutorial

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 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:

  1. react-native-location
  2. react-native-geolocation-service

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:

We made a custom demo for .
No really. Click here to check it out.

$ 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:

React Native Setup

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.

React Native Geolocation: Welcome Screen

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:

React Native Geolocation: Longitude and Latitude

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.

React Native Geolocation: Request Permission to Access Location Data

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:

React Native Geolocation: Access Location Data Prompt

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:

  1. First, a location variable is declared (not assigned at this time) using the Let keyword so that it can be reassigned at some other time
  2. 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 the IF construct
  3. IF the permission is obtained from the user, using the getLatestLocation method, log the location to the console to ensure that you can see the app working at this point
  4. The ELSE part returns the getLatestLocation method, so long as permission was granted prior
  5. 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:

React Native Geolocation App Example

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.

: 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.

.
Emmanuel Oaikhenan I started coding JavaScript in 2017 and delved into DevOps in 2019. In that time, I worked on projects that exposed me to learning more about software development and gained the requisite soft skills for communicating with teammates and clients.

3 Replies to “React Native geolocation: A complete tutorial”

  1. 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”

  2. Thank you for reading the article Mushtaq! I do hope you found it useful. Thank you much more for pointing that out.

Leave a Reply