# Maps in React Native: A Step-by-Step Guide

# Introduction

Maps are everywhere and can be used for a wide range of purposes, allowing you to represent different types of data, and enabling powerful interactions for your users.

Whether you need to display store locations for a delivery app, show routes in a fitness app, or highlight nearby hospitals in a healthcare app, chances are you will need to deal with maps sooner or later.

In this series, we'll cover the basics of working with maps in React Native:

* Expo Project setup
    
* Google Cloud Console setup
    
    * Creating a Google project
        
    * Getting API keys for each platform
        
    * Setting up restrictions for each platform
        
        * Getting the required SHA-1 Certificate Fingerprint by building our app with EAS build
            
* Creating a basic map
    
* Requesting user permission to access their current location
    
* Displaying data within the map
    
* Handling user interactions.
    
* More!
    

These series are divided into two parts:

* **The boring (but needed) part:** Project setup, getting the API keys, building the app, and getting the SHA-1 Certificate (required for your API keys)
    
* **The fun part:** Start playing with maps and adding cool features.
    

By the end of this article, you’ll be done with the boring stuff, and you’ll have a basic map working in your app. The next article will cover the fun part, and will be released next week.

---

# Creating a new project

Let’s start by creating an empty react native project with Expo. I’ll be using the `expo-template-blank-typescript` to avoid dealing with TypeScript configurations.

```bash
npx create-expo-app -t expo-template-blank-typescript
```

---

# Adding react-native-maps

If you're working with maps in React Native, look no further than `react-native-maps`. It offers a lot of handy features, including markers, user location tracking, and event handling, as well as advanced functionalities like overlays and marker clustering.

Furthermore, you have the freedom to completely customize the appearance of your map to align with your brand or to support dark mode.

Run the following command in the root of your project to add `react-native-maps`

```bash
npx expo install react-native-maps
```

By using the `npx expo install` command, we make sure that we get the right version of `react-native-maps` for the Expo SDK version we are using. At the time I’m writing this article, the latest SDK version is 48.

---

# Setting up Google Maps SDK

While working with `react-native-maps`. You’ll need to use the **GOOGLE\_PROVIDER** to present a unified look and feel on both platforms. Because the Google provider relies on Google APIs for many features, we’ll need to get our API Keys and tie everything up within our Expo project so everything works as expected.

But there’s a catch. In order to properly setup your Android API key restrictions (highly recommended to protect your API key from unauthorized use), you’ll need to provide a **SHA-1 Certificate Fingerprint**. There are two ways you can get this certificate:

1. Build your app and upload your binary to the Google Play console.
    
2. Create a development build with [EAS build](https://docs.expo.dev/build/introduction/), the Expo service that allows you to build your apps in the cloud.
    

You’ll eventually need to upload your binary before publishing your app to the Play Store, but it involves many additional steps that are outside of the scope of this tutorial, so we’ll proceed with option 2.

## Creating a development build with EAS build

For this part of the tutorial, you’ll need to have an Expo account and install the `eas-cli` globally. If you don’t have an account already, please visit [https://expo.dev](https://expo.dev) and sign up.

If you are already using EAS and want to add maps to an existing project, you can skip the following steps

1. Once you have an Expo account, run the following command on your terminal to globally install the `eas-cli` package
    
    ```bash
    npm install -g eas-cli
    ```
    
2. Run the `eas login` command, and enter your username and password.
    
3. Once you are logged in, run the following command to set up your project.
    
    ```bash
    eas build:configure
    ```
    
    > Select all platforms when asked, so you can build for both platforms later.
    
4. After this step, your project will now include a new `eas.json` file where you can setup your different build profiles. For the scope of this article, we’ll use the “**preview**” profile that is already configured. Besides, Expo will create a new project for you. You can now visit [expo.dev](http://expo.dev) and search for your new project.
    
5. Update your `app.json` file to provide a package name for your Android app, and a bundle identifier for your iOS app.
  ```diff
  {
    "expo": {
      "name": "maps-demo",
      "slug": "maps-demo",
      "version": "1.0.0",
      "orientation": "portrait",
      "icon": "./assets/icon.png",
      "userInterfaceStyle": "light",
      "splash": {
        "image": "./assets/splash.png",
        "resizeMode": "contain",
        "backgroundColor": "#ffffff"
      },
      "assetBundlePatterns": ["**/*"],
      "ios": {
        "supportsTablet": true,
  +    "bundleIdentifier": "com.example.mapsdemo"
      },
      "android": {
        "adaptiveIcon": {
          "foregroundImage": "./assets/adaptive-icon.png",
          "backgroundColor": "#ffffff"
        },
  +    "package": "com.example.mapsdemo"
      },
      "web": {
        "favicon": "./assets/favicon.png"
      },
      "extra": {
        "eas": {
          "projected": "..."
        }
      }
    }
  }
  ```

1. Run the following command to create your first Android build
    
    ```bash
    eas build --platform android --profile preview
    ```
    

Follow the instructions, and EAS will proceed to create a new Android Keystore for you. This Keystore is used to sign the Android app during the build process, ensuring its security and integrity.

After signing the app, Expo will automatically start building your app in the cloud.

At this point, you can visit [https://expo.dev](https://expo.dev) and see your new project with the first build in progress.

![expo.dev home page](https://i.imgur.com/zka9SKo.png align="left")

This build can take a few minutes, but we can already get the SHA-1 Certificate we need. 😉

## Getting the SHA-1 Certificate Fingerprint

1. Go to [https://expo.dev](https://expo.dev) and click on your new project in the sidebar, as shown in the image above.
    
2. From your project dashboard, click on “**Credentials**” within the “**Configure**” section
    
    ![](https://i.imgur.com/VI2OGxu.png align="left")
    
3. With “**Android**” active in the top menu (active by default), click on your application identifier
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780790687/3fa7419e-b114-4179-a985-8441a74e49b7.png align="left")
    
4. Within the “**Android Keystore**” section, you’ll see your generated **SHA-1 Certificate Fingerprint**. Copy this, as you’ll need it below while setting up everything in Google Cloud Console.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780825653/ca58bb32-8cd2-49b7-939a-5dde6b6e8b44.png align="left")
    

## **Creating a project in Google Cloud Platform**

Before we can use Google as a Maps provider, it is essential to create a project in Google Cloud Platform. To set up your project, follow these steps:

1. Visit [**cloud.google.com**](http://cloud.google.com) and sign in.
    
2. Click on the dropdown at the top left corner.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780854416/1479f3bb-6280-45dd-912b-52baf0d4cbed.png align="left")
    
3. Click on "**New Project**" at the top right corner.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780878032/bbc5202e-1d02-4c5a-bb27-9b6f435a2671.png align="left")
    
4. Fill in the form and click on "**Create**", and wait until the project is created. It could take a few seconds or even minutes.
    
    > ***Warning: Once you confirm this form, you won’t be able to change your project id.***
    
5. Once the project creation is finished, you receive a notification like in the image below. Click “**Select project**” to set your new project as active, and you’ll be redirected to your new project’s dashboard.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780896305/ea1527b9-b23b-40e5-b638-5cf4acf7b097.png align="left")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780904144/5e0000eb-1374-4f76-9ad6-1e0e7b7293eb.png align="left")
    

## Enabling Google Maps SDK

With the new project created, we now need to enable Google Maps SDK. Let’s do that step-by-step:

1. Click on “**APIs & Services**”
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780927785/e6fc3d44-243d-4951-a40a-56090b3a4e3a.png align="left")
    
2. Click on “**Enable APIs and services**”
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780938690/a1cd52ea-cac9-4e13-a1ce-6c73b9a27342.png align="left")
    
3. We’ll need to enable “**Maps SDK for Android**” and “**Maps SDK for iOS**”.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780951594/bcedc576-efd6-4e88-9b80-ee967e947bd8.png align="left")
    
4. Let’s start with Android first. Click on the “**Maps SDK for Android**” card.
    
5. Next, click on “**Enable**”. This will take a few seconds, and you’ll get your API key.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686780976174/fdb88783-0d96-46e7-9ad1-3b6113c442f2.png align="left")
    
    > Make sure to store the key. You’ll need it later.
    
6. Repeat the same steps for iOS to enable “**Maps SDK for iOS**”
    
    > At least in my case, I didn’t get an API key for iOS after enabling it. So we’ll create an API key later in this article.
    

You now have both services enabled for your Google Console project. The next step is to set up a few app restrictions for each platform.

## Setting up “App restrictions”

Setting up app restrictions while working with the Google Maps SDK is highly recommended for several reasons:

1. **Security**: By setting up app restrictions, you can ensure that only your authorized apps are able to use the Google Maps SDK with your API key.
    
2. **Quota management**: The Google Maps SDK has usage limits and quotas associated with it. By setting up app restrictions, you can effectively manage and monitor the usage of the SDK for each of your authorized apps. This helps prevent excessive usage that could lead to unexpected costs.
    
3. **API key management**: App restrictions provide an additional layer of protection for your API key. If you need to revoke access for a specific app or if you suspect unauthorized usage, you can easily update the app restrictions to disable access for that app without affecting other authorized apps.
    

### App restrictions for Android

1. Within “APIs & Services”, click on the “**Credentials**” button in the sidebar, and then click on “**Maps API Key**”
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686781154853/9605f2f3-ceda-44d6-8915-0f6fff78432b.png align="left")
    
2. Update the name of the API key so it’s easier to differentiate between Android and iOS. I added the “Android” prefix, but feel free to choose the name you want.
    
3. Within the “**Set an application restriction**” section, choose “**Android apps**”
    
4. A new section called “**Android restrictions**” will appear. Click on the “**\+ Add**” button, and complete the form with your **package name** (needs to match with your `app.json` file) and your **SHA-1 certificate fingerprint**.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686781171775/8a6dddf8-884a-421d-b8cd-df123182a81f.png align="left")
    
5. Click “**Done**” and then “**Save**” to confirm your new restrictions.
    
6. Copy your API key and add it to your `app.json` file:
  ```diff
  {
    "expo": {
      ...
      "android": {
        ...
        "package": "com.example.mapsdemo",
  +     "config": {
  +       "googleMaps": {
  +         "apiKey": "YOUR_ANDROID_API_KEY"
  +       }
  +     }
      }
    }
  }
  ```
    

### App restrictions for iOS

1. Go back to the "**Credentials**" section and click on the "**Create credentials**" menu. then click on "**API key"**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686781251496/a4f6a806-c066-460f-b776-849c0f325bbf.png align="left")
    
2. Google will generate a new API Key. Copy it for later. Then, close the modal and click on the new API to set up the restrictions, the same as you did for Android before.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686781298220/02cd69bb-aa4b-4415-a9fb-1bed435cde84.png align="left")
    
3. Update the name of the API key so it’s easier to differentiate between Android and iOS. I added the “iOS” prefix.
    
4. Within the “**Set an application restriction**” section, choose “**iOS apps**”
    
5. A new section called “**iOS restrictions**” will appear. Click on the “**\+ Add**” button, and complete the form with your **bundle identifier** (it needs to match with your `app.json` file)
    
6. Click “**Done**” and then “**Save**” to confirm your new restrictions.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686781318026/7bdeaa83-5f02-4ec2-a4c0-43f71c1fa41e.png align="left")
    
7. Copy your API key and update your `app.json` file like this
  ```diff
  {
    "expo": {
      ...
      "ios": {
        "bundleIdentifier": "com.example.mapsdemo",
  +     "config": {
  +       "googleMapsApiKey": "YOUR_IOS_API_KEY"
  +     }
      },
      ...
    }
  }
  ```

---

# Adding a basic map

Update your `App.tsx` file to render a **MapView** that covers the entire screen

```typescript
import React from "react";
import { StyleSheet } from "react-native";
import MapView, { PROVIDER_GOOGLE } from "react-native-maps";

export default function App() {
  return (
    <MapView
      provider={PROVIDER_GOOGLE} // Specify Google Maps as the provider
      style={styles.map}
      initialRegion={{
        latitude: -34.603738,
        longitude: -58.38157,
        latitudeDelta: 0.01,
        longitudeDelta: 0.01,
      }}
    />
  );
}

const styles = StyleSheet.create({
  map: {
    flex: 1
  },
});
```

Here are a few things to mention about this code:

* The `provider` prop is set to **PROVIDER\_GOOGLE**, indicating the use of Google Maps as the map provider for both platforms.
    
* The `initialRegion` prop defines the initial center and zoom level of the map using the specified latitude, longitude, and delta values.
    
* For the map styles, we are using `flex:1`, so we can fill the screen with the map.
    

You can now run your app with `npm start` or `yarn start`. If everything went as expected, you should see your full-screen map ✨

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686781357514/913b8022-2dc2-4659-8492-b30842e9073e.png align="left")

Congrats! You are done with the boring stuff! Stay tuned for the next article, where we’ll start working with our map to add new features, track user events, and more.

# Final thoughts

I saw a few articles that talked about how to use maps in React Native, but I couldn’t find an article focused on the boring but important configurations required to use maps in a secure way, so my goal for this article was to address all those aspects that are usually overlooked.

Please let me know if you find it useful, and if you want me to cover specific topics about react-native-maps or React Native in general.

Happy coding!
