June 11, 2019

Getting Started with Firestore and React Native

by Aman Mittal

Getting Started with Firestore and React Native

Firebase is a complete package when it comes to building mobile applications and integrating them with a serverless service.

Managed by Google, Firebase includes services like mobile analytics, push notifications, crash reporting, and out-of-the-box provides email as well as social authentication.

As a React Native developer, by using Firebase you can start building an MVP (minimum viable product) by keeping the costs low and utilizing your time and effort in building the application quite faster than adopting a traditional approach by building your own custom backend solution.

In this tutorial, you will learn how to integrate the Firestore cloud database in a React Native app. We will create a bare minimum demo application from scratch with the help of Firebase & React Native to see how they work together and understand the differences between a Firestore database and a Real-time Database in Firebase.

To learn more about what Firestore is and how it differs from the Real-time Database offered by Firebase, please refer to the official documentation here.

The complete code for this tutorial is available in this GitHub repository.

Setup a Firebase Project

To get started, you need a Firebase account. To sign-up or log-in for one, visit the Firebase Console and click on the button “Add Project”. In the next screen, fill the name of the project, check both the boxes for now and click on “Create Project”. Once the Firebase project is created, you will be welcomed by the home screen like below.

jscrambler-blog-getting-started-firestore-react-native-1-1

Create a New React Native Project

To set up a new React Native project, make sure you have react-native CLI installed. If not, you can run the command below.

npm i -g react-native-cli

Next, run the command to generate a new React Native app.

react-native init RNFirestoreDemo

When the above command is done running, traverse into the project directory using cd rnFirebaseDemo. Now, let’s check if everything is working correctly and our React Native application has been properly initialized by running one of the following commands.

# on macOS
react-native run-ios

# For Windows/Unix users
react-native run-android

Connecting Firebase with React Native App

To connect Firebase SDK with a React Native app, you need an API key and to store in the client side app somewhere (probably as environmental variables when deploying the app in production).

Click on the settings icon in the sidebar menu in the Firebase console and go to Project settings. Look out for "Your apps" section where all the platforms (iOS, Android, and web) are available. Click on the Web as shown below.

jscrambler-blog-getting-started-firestore-react-native-2

Next, copy only the config variable in a new file called config/firebase.js inside the React Native project. Initially, the file might look like the snippet below.

// firebase.js

import firebase from "firebase/app"

const config = {
   apiKey: "AIzaXXXXXXXXXXXXXXXXXXXXXXX",
   authDomain: "rnfirebXXX-XXXX.firebaseapp.com",
   databaseURL: "rnfirebXXX-XXXX.firebaseapp.com",
   projectId: "rnfirebase-XXXX",
   storageBucket: "rnfirebase-XXXX.appspot.com",
   messagingSenderId: "XXXXXXX",
   appId: "XXXX
}

Where all the XXXXs are the key values. Now, you are required to add Firebase SDK in the React Native app.

You could have imported Firebase from just Firebase in the above snippet. The reason we are using firebase/app is that /app only adds the core of the Firebase services. Right now, to integrate Firebase with our React app, we only need the initializeApp() method to pass all the keys required to configure from Firebase.

To proceed, run the following command from your terminal. Do note that the React Native CLI by default uses yarn instead of npm as the JavaScript package manager to install dependencies.

yarn add firebase

Lastly, do not forget to export the Firebase object instance that you will be using in the React app later.

// firebase.js

//...
firebase.initializeApp(config)

export default firebase

Adding Environment Variables

To make sure sensitive data like API keys are always safe, there is a mechanism of .env files. In JavaScript programming, what are you going to see is a very common practice, at least in the case of web applications.

In React Native, there is a way to save API Keys and other sensitive information without integrating any native code. This is provided by react-native-dotenv. This package allows you to import environment variables from a .env file. To get started, install this dependency by running the command below.

yarn add --dev react-native-dotenv

After it has successfully installed, open the babel.config.js file and the following.

module.exports = {
  presets: ["module:metro-react-native-babel-preset", "module:react-native-dotenv"]
}

Create a new file called .env in the root directory and add all the Firebase config values here (hint: the config value we added earlier in the firebase.js file).

API_KEY=XXXX
AUTH_DOMAIN=XXXX
DATABASE_URL=XXXX
PROJECT_ID=XXXX
STORAGE_BUCKET=XXXX
MESSAGING_SENDER_ID=XXXX
APP_ID=XXXX

Again, the Xs represent the actual values from your configuration object. When done with this step, open firebase.js and modify it accordingly.

// firebase.js
import firebase from "firebase"

import {
  API_KEY,
  AUTH_DOMAIN,
  DATABASE_URL,
  PROJECT_ID,
  STORAGE_BUCKET,
  MESSAGING_SENDER_ID,
  APP_ID
} from "react-native-dotenv"

const config = {
  apiKey: API_KEY,
  authDomain: AUTH_DOMAIN,
  databaseURL: DATABASE_URL,
  projectId: PROJECT_ID,
  storageBucket: STORAGE_BUCKET,
  messagingSenderId: MESSAGING_SENDER_ID,
  appId: APP_ID
}

firebase.initializeApp(config)

export default firebase

Protect your Code with Jscrambler

Creating a Firestore Database

In the Database section, choose the cloud Firestore and go to the second tab called Rules. If you are enabling Firestore for the first time, chances are you need to set the database security rules to test mode. This is where the Firebase SDK will allow anyone (who has access to the config keys) to read and write to the database. That said, this section should look like below.

service cloud.firestore {
 match /databases/{database}/documents {
   match /{document=**} {
     allow read, write;
   }
 }
}

Open firebase.js and import the firestore instance.

// firebase.js

// after other imports
import "firebase/firestore"

// just before export default statement
export const firestore = firebase.firestore()

Exporting the Firestore instance will let you use it to query the database. Now, go back to the Firebase console and go to the Data tab under Firestore.

jscrambler-blog-getting-started-firestore-react-native-3

You will notice that there is currently no data inside the database. Under the “Add Collection” column, you’ll find each collection that you might have in the database. Click on “Add Collection” and enter the name of the collection as shown below.

jscrambler-blog-getting-started-firestore-react-native-4

Click Next and enter two fields. One for the title of the book and the other one for the author's name. By default, the ID for each document will be auto-generated if the above option Auto-id is selected or remained untouched. Note that both of these fields represent one document as a whole.

Notice that we have not defined value for both the fields. Also, both the fields are of data type string. Of course, there are other data types available and supported by Firestore. You can try to add the first document to this collection by pressing the save button.

Adding Data to Firestore

In this section, let us build a React Native component that will in return allow us to communicate with the Firestore database. In other words, it will allow us to perform CRUD operations.

We are going to build a bare minimum app. The UI will have two input fields and a button to add the value of each input field to the Firestore database. Each input field will represent the title and the author of the book (in the previous section, we did create a collection in the database called "books").

Open the App.js file which, at this moment, contains a lot of boilerplate code. Define an initial state to the App component. Then, inside the render function, this component has two input fields for the title and the author and a button to add the book.

import React, { Component } from "react"
import { StyleSheet, SafeAreaView, Text, View, TextInput, Button } from "react-native"

export default class App extends Component {
  state = {
    title: "",
    author: ""
  }

  render() {
    const { title, author } = this.state

    return (
      <SafeAreaView style={styles.container}>
        <View style={styles.inputContainer}>
          <TextInput
            value={title}
            placeholder='Title of the book'
            style={styles.textInput}
            onChangeText={value => this.setState({ title: value })}
          />
          <TextInput
            value={author}
            placeholder='Name of the Author'
            style={styles.textInput}
            onChangeText={value => this.setState({ author: value })}
          />
          <Button onPress={() => alert("Add the book")} title='Add the book' color='#841584' />
        </View>
      </SafeAreaView>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#F5FCFF"
  },
  inputContainer: {
    margin: 30
  },
  textInput: {
    height: 30,
    textAlign: "center",
    color: "#333333",
    marginBottom: 10,
    fontSize: 24,
    borderWidth: 1,
    borderBottomColor: "#111111"
  }
})

Once you are done modifying the App component, open two terminal windows simultaneously. Run the following commands in separate terminal windows.

# First terminal window
npm start

# Second terminal window (for iOS)
react-native run-ios

# Second terminal window (for Android)
react-native run-android

Once the compilation is done, you will get the following result.

Let us try and add a book.

Since the application right now is not throwing an error, this means it did work. To verify, go to Firebase console and the Firestore database section. You will see the name of the collection as well as the document with an autogenerated ID containing the input values we just entered above.

jscrambler-blog-getting-started-firestore-react-native-8

Conclusion

Congratulations! You have completed the tutorial. The demonstration in this tutorial is the bare minimum but you can go ahead and write features like reading and deleting an item from the Firestore database in the React Native app. Think of it as a challenge.

Lastly, if you're building React Native apps with sensitive logic, be sure to protect them against code theft and reverse-engineering by following our guide.