Skip to content

React Native Part 8 - CRUD with Static Data

Published: at 09:09 AM

React Native (Part 8): To-Do App with Firebase Firestore

In this tutorial, you will create a simple to-do app in React Native using Firebase Cloud Firestore to store and manage data.

Prerequisites

Project Folder Structure

Before diving into the code, here is a breakdown of the folder structure for this project:

ToDoApp/

├── firebase.js          # Firebase configuration file
├── App.js               # Main application file

├── assets/              # Asset files like images, fonts (if any)

├── node_modules/        # Automatically generated; contains dependencies

├── .gitignore           # Specifies files to be ignored by Git
├── app.json             # Application configuration
├── babel.config.js      # Babel configuration
├── package.json         # Project metadata and dependencies
└── package-lock.json    # Automatically generated; dependency tree

Explanation of Main Files

Step 1: Setting Up Your React Native Project

  1. Create a new React Native project using Expo:

    npx create-expo-app ToDoApp
    cd ToDoApp
    npm start
    
  2. Install Firebase:

    npm install firebase
    

Step 2: Setting Up Firebase

  1. Go to the Firebase Console and create a new project.

  2. Add a new Android or iOS app to your Firebase project:

    • iOS: Download the GoogleService-Info.plist file and add it to the root of your project.
    • Android: Download the google-services.json file and add it to the android/app directory.
  3. Create a Cloud Firestore database:

    • In the Firebase Console, go to Firestore Database > Create Database.
    • Choose Start in test mode (open access for development purposes).
    • Select a location and click Enable.
  4. Copy the Firebase SDK configuration from the Firebase Console’s project settings.

Step 3: Integrating Firebase in React Native

  1. Create a file firebase.js in the root directory and set up Firebase:

    firebase.js

    // firebase.js
    import { initializeApp } from "firebase/app";
    import { getFirestore } from "firebase/firestore";
    
    const firebaseConfig = {
      apiKey: "YOUR_API_KEY",
      authDomain: "YOUR_AUTH_DOMAIN",
      projectId: "YOUR_PROJECT_ID",
      storageBucket: "YOUR_STORAGE_BUCKET",
      messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
      appId: "YOUR_APP_ID",
    };
    
    // Initialize Firebase
    const app = initializeApp(firebaseConfig);
    const db = getFirestore(app);
    
    export { db };
    

Explanation

Step 4: Building the To-Do Application

  1. Open App.js and implement the following:

    App.js

    import React, { useState, useEffect } from "react";
    import {
      View,
      TextInput,
      Button,
      FlatList,
      Text,
      TouchableOpacity,
      StyleSheet,
    } from "react-native";
    import {
      collection,
      addDoc,
      getDocs,
      deleteDoc,
      doc,
    } from "firebase/firestore";
    import { db } from "./firebase";
    
    export default function App() {
      const [task, setTask] = useState("");
      const [tasks, setTasks] = useState([]);
    
      // Fetch tasks from Firestore
      useEffect(() => {
        const fetchTasks = async () => {
          const querySnapshot = await getDocs(collection(db, "tasks"));
          const tasksList = querySnapshot.docs.map(doc => ({
            ...doc.data(),
            id: doc.id,
          }));
          setTasks(tasksList);
        };
        fetchTasks();
      }, []);
    
      // Add a new task
      const addTask = async () => {
        if (task === "") return;
    
        try {
          const docRef = await addDoc(collection(db, "tasks"), { text: task });
          setTasks([...tasks, { text: task, id: docRef.id }]);
          setTask("");
        } catch (e) {
          console.error("Error adding task: ", e);
        }
      };
    
      // Delete a task
      const deleteTask = async id => {
        try {
          await deleteDoc(doc(db, "tasks", id));
          setTasks(tasks.filter(task => task.id !== id));
        } catch (e) {
          console.error("Error deleting task: ", e);
        }
      };
    
      return (
        <View style={styles.container}>
          <TextInput
            style={styles.input}
            placeholder="Enter a task"
            value={task}
            onChangeText={setTask}
          />
          <Button title="Add Task" onPress={addTask} />
          <FlatList
            data={tasks}
            keyExtractor={item => item.id}
            renderItem={({ item }) => (
              <View style={styles.taskContainer}>
                <Text style={styles.taskText}>{item.text}</Text>
                <TouchableOpacity onPress={() => deleteTask(item.id)}>
                  <Text style={styles.deleteText}>Delete</Text>
                </TouchableOpacity>
              </View>
            )}
          />
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        padding: 20,
        marginTop: 50,
      },
      input: {
        borderWidth: 1,
        borderColor: "#ccc",
        padding: 10,
        marginVertical: 10,
        borderRadius: 5,
      },
      taskContainer: {
        flexDirection: "row",
        justifyContent: "space-between",
        alignItems: "center",
        padding: 10,
        borderBottomWidth: 1,
        borderBottomColor: "#ccc",
      },
      taskText: {
        fontSize: 18,
      },
      deleteText: {
        color: "red",
        fontWeight: "bold",
      },
    });
    

Explanation

Step 5: Running the App

Summary

In this guide, you:

Next Steps

This is the foundation of using Firebase with React Native for building a to-do app. Feel free to expand and customize it!


Previous Post
React Native Part 7 - CRUD with Static Data
Next Post
How to add an estimated reading time in AstroPaper