Create a React Native App with Google Map using Expo.io

Mofizur Rahman
Apr 25, 2018 · 7 min read

Its often useful to represent information in a map as key-value pairs. For instance, the location of certain landmarks or areas of impact can be represented in a map to provide an intuitive way to structure data.

What You Need

  • Node.js
  • create-react-native-app command line tool

To get started quickly with set up you can follow this post.

Image for post
Image for post

Setup

The following setup is for Android phones. If you use iPhone simulator or load the app in an iPhone you could skip to the code part.

  • Once the application is created from the project folder open app.json
Image for post
Image for post
  • Your app.json looks something like this
  • We are going to install expo command line tools
npm install -g expo
  • Go to expo.io and create and account.
  • From terminal
expo login
  • You will be prompted to enter your username/email address and password.
Image for post
Image for post
  • You should see a message like above.
  • We are going to update our app.json with the following
{
"expo": {
"name": "Your App Name",
"icon": "./path/to/your/app-icon.png",
"version": "1.0.0",
"slug": "your-app-slug",
"sdkVersion": "XX.0.0",
"ios": {
"bundleIdentifier": "com.yourcompany.yourappname"
},
"android": {
"package": "com.yourcompany.yourappname"
}
}
}
  • The iOS bundleIdentifier and Android package fields use reverse DNS notation, but don't have to be related to a domain. Replace "com.yourcompany.yourappname" with whatever makes sense for your app.
  • You’re probably not surprised that name, icon and version are required.
  • slug is the url name that your app's JavaScript is published to. For example: expo.io/@community/native-component-list, where community is my username and native-component-list is the slug.
  • The sdkVersion tells Expo what Expo runtime version to use, which corresponds to a React Native version. Although "XX.0.0" is listed in the example, you already have an sdkVersion in your app.json and should not change it except when you want to update to a new version of Expo.

With all the info my app.json is the following.

{
"expo": {
"name": "map-cuny",
"icon": "./assets/icon.png",
"version": "1.0.0",
"slug": "map-cuny",
"sdkVersion": "26.0.0",
"ios": {
"bundleIdentifier": "com.codingmechanic.mapcuny"
},
"android": {
"package": "com.codingmechanic.mapcuny"
}
}
}
  • Once the app.json is all set we can then build the android standalone app from terminal.
expo build:android

This will take a few minutes. Get some coffee in the mean time.

  • Once the Build is completed run expo fetch:android:keystore
Image for post
Image for post
  • This would generate the map-cuny.jks file and return the keystore password . We will need the key store password in a second.
  • Run keytool -list -v -keystore map-cuny.jks . For your app replace map-cuny.jks with your .jks file.
  • If you enter the correct keystore password you should see something like this.
Image for post
Image for post
  • What we are interested in is the SHA1 key. We will use that in Google Cloud Platform in a minute.

Google Cloud Platform Setup

Image for post
Image for post
  • Click on Create
Image for post
Image for post
  • Give your project a meaningful name
  • Once created you should be taken to your app dashboard.
Image for post
Image for post
  • Go to APIs and Services on the left side bar
Image for post
Image for post
  • Go to Library on the left side bar
Image for post
Image for post
  • Select Google Maps Android API

(If the UI changes over the time and Google Maps Api is not on the screen, You can always search for the Api in the search bar)

  • Enable Google Maps Android API
Image for post
Image for post
  • The Warning basically asks us to “Create Credentials” for our app to be able to use google maps api.
  • Click on Create Credentials.
Image for post
Image for post
  • Click on API Key
Image for post
Image for post
  • In the API restrictions tab select Google Maps Android API
Image for post
Image for post
  • Click on create. Copy the api key that was generated.
  • Go Back to app.json
"android": {
"package": "com.codingmechanic.mapcuny",
"config": {
"googleMaps": { "apiKey": "<Your API Key>" }
}
}
  • Add config to android
  • Setup is complete

Code

We are now ready to start coding. Just to see we have the setup right, we will just put a Map View in the screen. Update your App.js with the following

import React from "react";
import { StyleSheet, Text, View } from "react-native";
import { MapView } from "expo";
export default class App extends React.Component {
render() {
return (
<MapView
style={{
flex: 1
}}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}}
/>
);
}
}

In line 3 we are importing MapView from expo . This MapView is just a wrapper of the React Native Maps library by AirBnB. In Render we render the MapView with style flex:1 So that it takes the entire screen and give it an initial region. This location is of somewhere in SF.

Image for post
Image for post
Image for post
Image for post
iPhone 7+ and One Plus 3

I ran the app in my iPhone 7+ and One Plus 3 device. And as seen above the Map is rendered by Apple MapKit or Google Maps depending on the platform.

This is all fine and working but we would like to show something in this map. Some location info that will be most useful in a map form.

For this demo I will use NYC Bike Data. This data is publicly available and does not require any authentication or token. For our purposes this is the easiest data to work with.

To get data we will be using fetch .

constructor(props) {
super(props);

this.state = {
isLoading: true,
markers: [],
};
}
  • First we add a constructor above the Render function.
  • isLoading flag is there to denote the end of fetching.
  • We will store the bike stop locations in the markers array.
  • Create a method called fetchMarkerData() and add the following code
fetchMarkerData() {
fetch('https://feeds.citibikenyc.com/stations/stations.json')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
markers: responseJson.stationBeanList,
});
})
.catch((error) => {
console.log(error);
});
}
  • We now call the fetchMarkerData() from life cycle method componentDidMount() (More about life cycle methods on here)
  • Life Cycle methods are not react native specific and come from react.js
  • We add the code
componentDidMount() {
this.fetchMarkerData();
}
  • Now when the component mounts the fetchMarkerData will be called and when data is received from the api we will update our state
  • Now its time to render all the markers
<MapView
style={{ flex: 1 }}
region={{
latitude: 40.76727216,
longitude: -73.99392888,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
{this.state.isLoading ? null : this.state.markers.map((marker, index) => {
const coords = {
latitude: marker.latitude,
longitude: marker.longitude,
};

const metadata = `Status: ${marker.statusValue}`;

return (
<MapView.Marker
key={index}
coordinate={coords}
title={marker.stationName}
description={metadata}
/>
);
})}
</MapView>
  • What is happening is we are checking if the isLoading flag is true. If so we are returning null else we are mapping over all the marker datas stored in our state and returning a Marker object for each marker in the array.
  • We can then run the app the same way for Android and iPhone
Image for post
Image for post
Image for post
Image for post
Rendering the Bike positions in iPhone and Pixel 2 XL

You may want to use google maps on you iOS app as well. There are a few benefits from using google maps. They have more data on places outside the US. So if you app targets a global audience google maps may be the better option.

  • Go to Google Cloud Platform Dashboard and select your project. (It generally opens to the last open project anyway)
  • Go to APIs and Services
  • Go to Library
  • Select Google Maps SDK for iOS
  • Enable
  • Go to Credentials
  • Create Credentials
  • API Credentials
  • Click on Restrict Key
  • Select iOS Application on Application Restrictions
  • Select Google Maps SDK for iOS on API Restriction
  • Enter you Bundler ID for iOS app from app.json
  • Save and Copy the api key
  • In app.json add googleMapsApiKey
"ios": {
"bundleIdentifier": "com.codingmechanic.mapcuny",
"config": {
"googleMapsApiKey": "YOUR IOS API KEY HERE"
}
},
  • In App.js in the MapView pass a new prop called provider and set it to
    "google"
<MapView
style={{ flex: 1 }}
provider="google"
region={{
latitude: 40.76727216,
longitude: -73.99392888,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}}
>
Image for post
Image for post

Further Readings

  • MapView Expo
  • MapView Docs
  • The code for this demo is available in this Git Repo
  • The project is available to view in this Expo repo. (iOS wont allow you to open someone else’s project in your device. But if you have an Android you could use Expo Client to test the app out in your phone. You can always run the app on the web)

NYC⚡️DEV

NYC Developer Community

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store