How To Use Firebase Firestore in React Native - Complete Guide

In this tutorial, you will learn how to use Firebase Firestore in a React Native app. We will be building a basic todo app with all the examples given. After each code snippet, there will be full documentation on what that code does.

Setting up the React Native app

First, we need to set up the React Native app. To do this, we'll be using the React Native CLI.

  1. Install the React Native CLI
npm install -g react-native-cli
  1. Create a new React Native app
react-native init MyReactNativeApp
  1. Run the app on a simulator or device
react-native run-ios

Adding all Firebase dependencies

Now that we have our React Native app set up, we can add all the Firebase dependencies.

  1. Install the Firebase module
npm install --save firebase
  1. Add the Firebase config to your React Native app
// App.js

import firebase from 'firebase'

firebase.initializeApp({
  apiKey: 'YOUR_API_KEY',
  authDomain: 'YOUR_AUTH_DOMAIN',
  databaseURL: 'YOUR_DATABASE_URL',
  projectId: 'YOUR_PROJECT_ID',
  storageBucket: 'YOUR_STORAGE_BUCKET',
  messagingSenderId: 'YOUR_MESSAGING_SENDER_ID',
  appId: 'YOUR_APP_ID'
})

Setting up Firestore read and write access rules

Next, we need to set up the Firestore read and write access rules. We can do this in the Firebase console.

  1. Log in to the Firebase console
  2. Select your project
  3. Go to the Database tab
  4. Click on the Rules tab
  5. Set the read and write rules to true, as shown below:
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

Writing to Firestore from React Native

Now that we have our Firestore access rules set up, we can start writing data to Firestore from our React Native app.

  1. Add a function to write data to Firestore
// App.js

// Function to write data to Firestore
const writeDataToFirestore = async (collection, data) => {
  try {
    const ref = firebase.firestore().collection(collection).doc()
    const response = await ref.set(data)
    return response
  } catch (error) {
    return error
  }
}

This function takes two arguments - the name of the Firestore collection and the data that we want to write. It creates a new document in the specified collection and sets the data.

  1. Call the writeDataToFirestore function
// App.js

const data = {
  title: 'My first todo item',
  description: 'This is my first todo item',
  completed: false
}

writeDataToFirestore('todos', data)

This code calls the writeDataToFirestore function with the collection name and the data that we want to write.

Reading single objects from Firestore

Now that we can write data to Firestore, let's learn how to read single objects from Firestore.

  1. Add a function to read data from Firestore
// App.js

// Function to read data from Firestore
const readDataFromFirestore = async (collection, docId) => {
  try {
    const ref = firebase.firestore().collection(collection).doc(docId)
    const response = await ref.get()
    return response
  } catch (error) {
    return error
  }
}

This function takes two arguments - the name of the Firestore collection and the document ID of the object that we want to read. It fetches the object from the specified collection and document ID.

  1. Call the readDataFromFirestore function
// App.js

const docId = 'some-unique-document-id'

readDataFromFirestore('todos', docId).then(doc => {
  const data = doc.data()
  console.log(data)
})

This code calls the readDataFromFirestore function with the collection name and the document ID of the object that we want to read. It then logs the data to the console.

Reading & displaying lists of objects

Now that we can read single objects from Firestore, let's learn how to read and display lists of objects.

  1. Add a component to read and display data
// TodoList.js

import React, { useState, useEffect } from 'react'
import { Text, View, FlatList } from 'react-native'

// Function to read data from Firestore
const readDataFromFirestore = async (collection) => {
  try {
    const ref = firebase.firestore().collection(collection)
    const response = await ref.get()
    return response
  } catch (error) {
    return error
  }
}

const TodoList = () => {
  const [todos, setTodos] = useState([])

  useEffect(() => {
    readDataFromFirestore('todos').then(docs => {
      const todos = docs.docs.map(doc => doc.data())
      setTodos(todos)
    })
  }, [])

  return (
    <View>
      <FlatList
        data={todos}
        keyExtractor={(todo) => todo.id}
        renderItem={({ item }) => (
          <View>
            <Text>{item.title}</Text>
            <Text>{item.description}</Text>
          </View>
        )}
      />
    </View>
  )
}

export default TodoList

This component reads the todos collection from Firestore and displays them in a FlatList.

  1. Render the component
// App.js

import TodoList from './TodoList'

// ...

<TodoList />

This code renders the TodoList component in the app.

Listening to real-time updates

Now that we can read and display lists of objects, let's learn how to listen to real-time updates.

  1. Add a function to listen for real-time updates
// App.js

// Function to listen for real-time updates
const listenToRealTimeUpdates = async (collection) => {
  try {
    const ref = firebase.firestore().collection(collection)
    const response = await ref.onSnapshot(snapshot => {
      const todos = snapshot.docs.map(doc => doc.data())
      setTodos(todos)
    })
    return response
  } catch (error) {
    return error
  }
}

This function takes one argument - the name of the Firestore collection. It listens for real-time updates to the specified collection and sets the data in the state.

  1. Call the listenToRealTimeUpdates function
// App.js

listenToRealTimeUpdates('todos')

This code calls the listenToRealTimeUpdates function with the collection name.

Batch updates to improve performance

Now that we can listen to real-time updates, let's learn how to batch update data to improve performance.

  1. Add a function to batch update data
// App.js

// Function to batch update data
const batchUpdateData = async (collection, data) => {
  try {
    const ref = firebase.firestore()
    const batch = ref.batch()
    data.forEach(doc => {
      const docRef = ref.collection(collection).doc(doc.id)
      batch.update(docRef, doc)
    })
    const response = await batch.commit()
    return response
  } catch (error) {
    return error
  }
}

This function takes two arguments - the name of the Firestore collection and the data that we want to update. It creates a batch update and updates the data in the specified collection.

  1. Call the batchUpdateData function
// App.js

const data = [
  {
    id: 'some-unique-document-id',
    title: 'My updated todo item',
    description: 'This is my updated todo item',
    completed: true
  }
]

batchUpdateData('todos', data)

This code calls the batchUpdateData function with the collection name and the data that we want to update.

How to Paginate Lists from Firestore

Finally, let's learn how to paginate lists from Firestore.

  1. Add a function to paginate data
// App.js

// Function to paginate data
const paginateData = async (collection, limit, after) => {
  try {
    const ref = firebase.firestore().collection(collection)
    const query = ref.orderBy('createdAt', 'desc').limit(limit)
    if (after) {
      query.startAfter(after)
    }
    const response = await query.get()
    return response
  } catch (error) {
    return error
  }
}

This function takes three arguments - the name of the Firestore collection, the limit of documents to return, and the document ID of the last document in the previous query. It queries the specified collection and returns the documents in the specified limit.

  1. Call the paginateData function
// App.js

const limit = 10
const after = 'some-unique-document-id'

paginateData('todos', limit, after).then(docs => {
  const todos = docs.docs.map(doc => doc.data())
  setTodos(todos)
})

This code calls the paginateData function with the collection name, the limit of documents to return, and the document ID of the last document in the previous query. It then sets the data in the state.

Conclusion

In this tutorial, you learned how to use Firebase Firestore in a React Native app. We built a basic todo app and explored all the features of Firestore. After each code snippet, we provided full documentation on what that code does.

We started by setting up the React Native app and adding all the Firebase dependencies. Then, we set up the Firestore read and write access rules. We learned how to write data to Firestore, read single objects from Firestore, read and display lists of objects, listen to real-time updates, batch update data to improve performance, and paginate lists from Firestore.

I hope you found this tutorial helpful and that you now have a better understanding of how to use Firebase Firestore in React Native.