Using Geolocation in React Native

Aman Mittal

React Native takes advantage of the Geolocation API that’s native on the web. This API returns different methods such as getCurrentPosition, and watchPosition which are available in React Native polyfilled. To demonstrate how to use it in a React Native app we will integrate it using react-native-cli.

Getting Started

Using react-native-cli means there are no templates and only little boilerplate code to get started. We will generate a project using the following command. If you do not have it installed on your local machine yet, please use the first command mentioned below:

# to install the cli
$ npm install -g react-native-cli

# to scafold an RN project
$ react-native init geo-example

So once the project directory is generated, traverse into it and run npm start to see if everything is installed correctly. If you are on Mac, you can use the ios simulator to verify. For Windows and Linux users, the Android emulator will be your friend.

Accessing the Geolocation API

The Geolocation API exists as a global navigator object in React Native, just like on the web. It’s accessible via navigator.geolocation in our source code and there is no need to import it.

For demonstration purposes, we’ll be using the getCurrentPosition method from the Geolocation API. This method allows a mobile app to request a user’s location and accepts three parameters: a success callback, an error callback and a configuration object.

navigator.geolocation.getCurrentPosition(
  position => {
    const location = JSON.stringify(position);

    this.setState({ location });
  },
  error => Alert.alert(error.message),
  { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);

The success callback above has a position argument that’s an object with the following properties if executed without any errors:

{
  "timestamp": 1533729980953.91
  "coords": {
    "accuracy": 5,
    "altitude": 0,
    "altitudeAccuracy": -1,
    "heading": -1,
    "latitude": 37.785834,
    "longitude": -122.406417,
    "speed": -1
  }
}

We will modify App.js in our React Native project to get started. We start by defining a basic class component that displays the text Find My Coords?:

App.js

import React, { Component } from "react";
import { View, Text } from "react-native";

export default class App extends Component {
  render() {
    return (
      <View>
        <Text>Find My Coords?</Text>
      </View>
    );
  }
}

Implementing Geolocation API

Now, let us implement the Geolocation API function getCurrentPosition in our app. Open App.js and write the following code.

App.js

import React, { Component } from "react";
import {
  Platform,
  StyleSheet,
  Text,
  View,
  Alert,
  TouchableOpacity
} from "react-native";

export default class App extends Component {
  state = {
    location: null
  };

  findCoordinates = () => {
    navigator.geolocation.getCurrentPosition(
      position => {
        const location = JSON.stringify(position);

        this.setState({ location });
      },
      error => Alert.alert(error.message),
      { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
    );
  };

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.findCoordinates}>
          <Text style={styles.welcome}>Find My Coords?</Text>
          <Text>Location: {this.state.location}</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

We start be importing TouchableOpacity. It’s a wrapper that responds accurately to user touches. In a React Native mobile app, you’ll be making use of that wrapper component quite often. Think of it as a button in a web application. This newly imported wrapper accepts an onPress prop that is going to trigger the method specified, findCoordinates in our case.

findCoordinates holds the logic for fetching a user’s location. We’re also using the local state to display coordinates from the data provided to us by position object. The text Find My Coords? now becomes clickable.

Let’s style things up a bit using React Native’s StyleSheet:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF"
  },
  welcome: {
    fontSize: 20,
    textAlign: "center",
    margin: 10
  },
  instructions: {
    textAlign: "center",
    color: "#333333",
    marginBottom: 5
  }
});

At this point, the example will not work as expected. We need to ask for permission to access a user’s location. Let’s fix that next.

Asking for Permission

In iOS, geolocation is enabled by default when a project is created using react-native-cli. To use it, you just need to include a key called <key>NSLocationWhenInUseUsageDescription</key> in the info.plist file, which is inside the ios/findCoordsApp directory.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleDisplayName</key>
	<string>findCoordsApp</string>
	[..]
	<key>NSLocationWhenInUseUsageDescription</key>
	<string></string>
	<key>NSAppTransportSecurity</key>
	<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
  [...]
</dict>
</plist>

For Android, we need to add the following line in the android/app/src/AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Wrapping Up

Now if you run your application you will see the following screen:

Screen before coordinates

Click on the text and you will be asked whether to allow the application to request for the user’s location:

Screen asking permission

If you press allow, you will see the following resulting screen:

Screen with coordinates

That was a very simple example, but you can go from there to create something more interesting/useful. If you want to learn more about working with the Geolocation API in a React Native application, please go through the official documentation.

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#