CRUD operations in react native

  

What is CRUD?

CRUD stands for:

Operation

Purpose

Create

Add a new document

Read

Fetch one or more documents

Update

Change existing document

Delete

Remove a document

In Firebase Firestore, documents are stored in collections.

 

SETUP FIRST

You must first initialize Firebase:

firebasedb.js

import { initializeApp } from "firebase/app";

import { getFirestore } from "firebase/firestore";

 

const firebaseConfig = {

  apiKey: "YOUR_KEY",

  authDomain: "YOUR_PROJECT.firebaseapp.com",

  projectId: "YOUR_PROJECT_ID",

  storageBucket: "YOUR_BUCKET",

  messagingSenderId: "YOUR_SENDER_ID",

  appId: "YOUR_APP_ID"

};

 

Perfect. Here’s a clear explanation of each Firebase CRUD method used with Firestore — no code, just explanations.


🔥 Firebase Firestore CRUD: Explained Simply

1. Create (add data) → addDoc()

  • Purpose: Add a new document to a Firestore collection.
  • What it does:
    • Automatically creates a unique ID for the document.
    • Stores your data in Firestore under that ID.
  • Example use case: When you register a new product or user.

📌 Summary:

“I want to create a new record in Firestore — use addDoc().”


🟨 2. Read (get data) → getDocs() or getDoc()

There are two variations:

a) getDocs()

  • Purpose: Fetch all documents from a specific collection.
  • Returns: A snapshot of all the documents in that collection.
  • Use case: Showing a list of all products or users.

b) getDoc()

  • Purpose: Fetch a single document by its ID.
  • Use case: When editing a specific user or item.

📌 Summary:

“I want to read one or all documents — use getDoc() or getDocs().”


🔄 3. Update (edit data) → updateDoc()

  • Purpose: Update fields inside an existing document.
  • What it does:
    • You provide the document's ID.
    • You specify which fields to update and their new values.
  • Use case: Editing a product's price or updating user details.

📌 Summary:

“I want to change some values in a document — use updateDoc().”


4. Delete (remove data) → deleteDoc()

  • Purpose: Remove a document from Firestore.
  • What it does:
    • Deletes a document permanently.
    • You must specify the document’s ID.
  • Use case: Deleting a user account or a product listing.

📌 Summary:

“I want to completely remove a document — use deleteDoc().”


🔑 Bonus: Helper Methods

🔹 collection()

  • Purpose: Refers to a collection (like a table in SQL).
  • Needed for: All operations (create, read, etc.) to tell Firebase where to act.

🔹 doc()

  • Purpose: Refers to a specific document by ID inside a collection.
  • Used in: updateDoc(), deleteDoc(), getDoc().

🔁 Order of Usage in a CRUD App

  1. addDoc() → to add new records
  2. getDocs() / getDoc() → to read data
  3. updateDoc() → to edit existing data
  4. deleteDoc() → to remove data

 

 

const app = initializeApp(firebaseConfig);

export const db = getFirestore(app);


1. 🟢 CREATE – Add a Product

import { collection, addDoc } from "firebase/firestore";

import { db } from "./firebasedb";

 

export const addProduct = async (name, price, company) => {

  try {

    await addDoc(collection(db, "products"), {

      name,

      price,

      company,

    });

    alert("Product added successfully!");

  } catch (error) {

    console.error("Error adding product:", error);

  }

};

 

2.  READ – Get All Products

import { collection, getDocs } from "firebase/firestore";

import { db } from "./firebasedb";

 

export const getProducts = async () => {

  try {

    const snapshot = await getDocs(collection(db, "products"));

    return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));

  } catch (error) {

    console.error("Error fetching products:", error);

  }

};

This will return an array like:

[

  { id: 'abc123', name: 'iPhone', price: 999, company: 'Apple' },

  { id: 'xyz456', name: 'Galaxy', price: 899, company: 'Samsung' },

]


3. 🟠 UPDATE – Modify a Product

import { doc, updateDoc } from "firebase/firestore";

import { db } from "./firebasedb";

 

export const updateProduct = async (id, updatedData) => {

  try {

    const ref = doc(db, "products", id);

    await updateDoc(ref, updatedData);

    alert("Product updated!");

  } catch (error) {

    console.error("Update error:", error);

  }

};

Example Usage:

updateProduct("abc123", {

  name: "iPhone 15",

  price: 1099,

});


4. 🔴 DELETE – Remove a Product

import { doc, deleteDoc } from "firebase/firestore";

import { db } from "./firebasedb";

 

export const deleteProduct = async (id) => {

  try {

    await deleteDoc(doc(db, "products", id));

    alert("Product deleted!");

  } catch (error) {

    console.error("Delete error:", error);

  }

};


📝 Summary

Action

Function Name

Firestore Method

Create

addProduct()

addDoc()

Read

getProducts()

getDocs()

Update

updateProduct()

updateDoc()

Delete

deleteProduct()

deleteDoc()


Real-world Flow Example

Imagine you're building a Product Admin Panel:

  • On screen load → Call getProducts() to show all products.
  • On "Add Product" → Call addProduct(name, price, company)
  • On "Edit" → Call updateProduct(id, updatedData)
  • On "Delete" → Call deleteProduct(id)

 

 

Perfect! Here's a complete working Firebase CRUD example using React Native (with Expo) for a Product Admin Panel, including UI and step-by-step explanations.


🔧 1. Project Setup

  1. Install Required Packages:

npx create-expo-app product-admin

cd product-admin

npm install firebase


📁 2. File Structure

project-root/

── config/

│   └── firebasedb.js       ← Firebase setup

── screens/

│   ── Home.js             ← Product list + delete/edit

│   ── AddProduct.js       ← Add or Update product

── App.js


🔥 3. firebasedb.js

// config/firebasedb.js

import { initializeApp } from "firebase/app";

import { getFirestore } from "firebase/firestore";

 

const firebaseConfig = {

  apiKey: "YOUR_KEY",

  authDomain: "YOUR_PROJECT.firebaseapp.com",

  projectId: "YOUR_PROJECT_ID",

  storageBucket: "YOUR_BUCKET",

  messagingSenderId: "YOUR_SENDER_ID",

  appId: "YOUR_APP_ID"

};

 

const app = initializeApp(firebaseConfig);

export const db = getFirestore(app);


📜 4. App.js – Navigation Setup

import { NavigationContainer } from '@react-navigation/native';

import { createNativeStackNavigator } from '@react-navigation/native-stack';

import Home from './screens/Home';

import AddProduct from './screens/AddProduct';

 

const Stack = createNativeStackNavigator();

 

export default function App() {

  return (

    <NavigationContainer>

      <Stack.Navigator initialRouteName="Home">

        <Stack.Screen name="Home" component={Home} />

        <Stack.Screen name="AddProduct" component={AddProduct} />

      </Stack.Navigator>

    </NavigationContainer>

  );

}


🏠 5. Home.js – List Products + Delete/Edit

// screens/Home.js

import { View, Text, FlatList, Button } from "react-native";

import { useEffect, useState } from "react";

import { db } from "../config/firebasedb";

import { collection, getDocs, deleteDoc, doc } from "firebase/firestore";

 

export default function Home({ navigation }) {

  const [products, setProducts] = useState([]);

 

  const fetchProducts = async () => {

    const snapshot = await getDocs(collection(db, "products"));

    const list = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));

    setProducts(list);

  };

 

  const handleDelete = async (id) => {

    await deleteDoc(doc(db, "products", id));

    fetchProducts(); // refresh list

  };

 

  useEffect(() => {

    fetchProducts();

  }, []);

 

  return (

    <View style={{ padding: 20 }}>

      <Button title="Add New Product" onPress={() => navigation.navigate("AddProduct")} />

 

      <FlatList

        data={products}

        keyExtractor={item => item.id}

        renderItem={({ item }) => (

          <View style={{ marginVertical: 10, borderBottomWidth: 1, paddingBottom: 10 }}>

            <Text>Name: {item.name}</Text>

            <Text>Price: {item.price}</Text>

            <Text>Company: {item.company}</Text>

            <Button title="Edit" onPress={() => navigation.navigate("AddProduct", { product: item })} />

            <Button title="Delete" color="red" onPress={() => handleDelete(item.id)} />

          </View>

        )}

      />

    </View>

  );

}


6. AddProduct.js – Add / Edit Product

// screens/AddProduct.js

import { View, TextInput, Button, Alert } from "react-native";

import { useEffect, useState } from "react";

import { db } from "../config/firebasedb";

import { collection, addDoc, updateDoc, doc } from "firebase/firestore";

 

export default function AddProduct({ navigation, route }) {

  const existing = route.params?.product;

 

  const [name, setName] = useState("");

  const [price, setPrice] = useState("");

  const [company, setCompany] = useState("");

 

  useEffect(() => {

    if (existing) {

      setName(existing.name);

      setPrice(String(existing.price));

      setCompany(existing.company);

    }

  }, [existing]);

 

  const handleSubmit = async () => {

    if (!name || !price || !company) {

      Alert.alert("Please fill all fields");

      return;

    }

 

    if (existing) {

      const docRef = doc(db, "products", existing.id);

      await updateDoc(docRef, { name, price: Number(price), company });

      Alert.alert("Product Updated");

    } else {

      await addDoc(collection(db, "products"), { name, price: Number(price), company });

      Alert.alert("Product Added");

    }

 

    navigation.navigate("Home");

  };

 

  return (

    <View style={{ padding: 20 }}>

      <TextInput placeholder="Name" value={name} onChangeText={setName} style={{ borderBottomWidth: 1, marginBottom: 10 }} />

      <TextInput placeholder="Price" value={price} onChangeText={setPrice} keyboardType="numeric" style={{ borderBottomWidth: 1, marginBottom: 10 }} />

      <TextInput placeholder="Company" value={company} onChangeText={setCompany} style={{ borderBottomWidth: 1, marginBottom: 20 }} />

      <Button title={existing ? "Update Product" : "Add Product"} onPress={handleSubmit} />

    </View>

  );

}


How It Works

Action

File

What Happens

Show products

Home.js

Calls getDocs() and shows data in a list

Add product

AddProduct.js

Calls addDoc() to save new data

Edit product

AddProduct.js

Calls updateDoc() if existing data present

Delete product

Home.js

Calls deleteDoc() with product ID


 

 

getDoc

getDoc() — What It Does

getDoc() is used to read a single document from Firestore.

 

Purpose

  • To fetch one specific document using its path (collection + document ID).
  • Useful when you know the ID of the document you want.

 

Syntax Overview

import { doc, getDoc } from "firebase/firestore";

 

const docRef = doc(db, "products", "abc123");

const docSnap = await getDoc(docRef);

 

Returns

It returns a DocumentSnapshot object, which includes:

  • exists(): to check if the document actually exists.
  • data(): the actual content of the document.
  • id: the document ID.

 

 

How It Works

  1. You create a document reference using doc().
  2. You call getDoc() and pass the reference.
  3. Firebase sends back the document's snapshot if it exists.
  4. You extract the data using .data().

 

 

Real-World Use Case

  • Admin Panel: Fetch and edit details of a specific product.
  • Profile Screen: Load the logged-in user’s data using their UID.
  • View Order: See full info of a single order by its ID.

 

 

 Caution

  • getDoc() only reads once. It doesn’t keep listening for changes. For real-time updates, you’d use onSnapshot() on a document.

 

 

Example

const docRef = doc(db, "users", "userId123");

const docSnap = await getDoc(docRef);

 

if (docSnap.exists()) {

  console.log("User data:", docSnap.data());

} else {

  console.log("No such document!");

}

 

0 Comments