Back
Mobile | Mon May 09 2022

CRUD Firebase

Hey there!

About this app

This is a fullstack app built with React Native, Firebase and Firestore. for those who don't know, Firebase is a cloud-based real-time database. It provide many features to manage your data, here we have a list of the most important to me 😅:

  • Authentication
  • Storage
  • Database
  • Firestore
  • Analytics
  • AdMob

If you would like to know more about Firebase, you can check out the docs.

Resources

Create project

  1. Create expo project
    npx create-expo-app CRUD_tutorial
  1. Create firebase project in the console
  2. Install dependencies
  • expo-constants dotenv: to manage the credentials of firebase.
  • react-native-gesture-handler react-native-screens react-native-safe-area-context @react-navigation/native-stack @react-navigation/native: to work with navigation.
  • react-native-svg: to render with SVGs in React native.
  • rn-emoji-keyboard: to show emojis.
  • firebase: Cloud service to save data.
npx expo install expo-constants dotenv react-native-gesture-handler react-native-screens react-native-safe-area-context  @react-navigation/native-stack @react-navigation/native react-native-svg rn-emoji-keyboard firebase@9.6.7

Set up the enviroment variables

  1. Create a file called .env. Next, add the firebase variables.
  2. Replace app.json with app.config.json
import "dotenv/config";
 
export default {
  // ...config,
    extra: {
      apiKey: process.env.API_KEY,
      authDomain: process.env.AUTH_DOMAIN,
      projectId: process.env.PROJECT_ID,
      storageBucket: process.env.STORAGE_BUCKET,
      messagingSenderId: process.env.MESSAGING_SENDER_ID,
      appId: process.env.APP_ID,
    },
  },
};
  1. Setting the firebase variables.

⚠Warning

expo-constants has the deprecated the method Constants.manifest. Now it is Constants.expoConfig.

//config/fb.js
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import Constants from "expo-constants";
 
// Firebase config
const firebaseConfig = {
  apiKey: Constants.expoConfig.extra.apiKey,
  authDomain: Constants.expoConfig.extra.authDomain,
  projectId: Constants.expoConfig.extra.projectId,
  storageBucket: Constants.expoConfig.extra.storageBucket,
  messagingSenderId: Constants.expoConfig.extra.messagingSenderId,
  appId: Constants.expoConfig.extra.appId,
  databaseURL: Constants.expoConfig.extra.databaseURL,
  //   @deprecated Constants.manifest
};
 
// initialize firebase
initializeApp(firebaseConfig);
export const database = getFirestore();

Create navigation

Create the navigation of the app.

// src\Navigation.js
const Stack = createNativeStackNavigator();
function MyStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Home" component={Home} />
      <Stack.Screen
        name="Add"
        component={Add}
        options={{ presentation: "modal" }}
      />
    </Stack.Navigator>
  );
}
export default function Navigation() {
  return (
    <NavigationContainer>
      <MyStack />
    </NavigationContainer>
  );
}

Create screen Add.js

In this section, it is developed the emojis and inputs to add the products.

  1. Pick emojis

the emoji Picker library allow us to pass a function in the prop onEmojiSelected to add the emoji.

const handlePick = (emojiObject) => {
  setNewItem({
    ...newItem,
    emoji: emojiObject.emoji,
  });
};
return (
  <EmojiPicker
    onEmojiSelected={handlePick}
    open={isOpen}
    onClose={() => setIsOpen(false)}
  />
);
  1. Pick info from input

the prop onChangeText returns the text to add it to state.

const [newItem, setNewItem] = React.useState({});
return (
  <RN.TextInput
    onChangeText={(text) => setNewItem({ ...newItem, name: text })}
    style={styles.inputContainer}
    placeholder="Product Name"
  />
);
  1. Save it in Firestore database
const onSend = async () => {
  const docRef = await addDoc(collection(database, "products"), newItem);
};

Code of the Add.js screen

Getting data in the screen Home.js

  1. Listen in real time to the collection products
React.useEffect(() => {
  const collectionRef = collection(database, "products");
  // a reference is the path in the database to access the data. it can be a collection or an specific document.
  const q = query(collectionRef, orderBy("createdAt", "desc"));
  const unsubscribe = onSnapshot(q, (querySnapshot) => {
    // onSnapshot is a listener that listens to changes in the database in realtime
    console.log("querySnapshot unsusbscribe");
    setProducts(
      querySnapshot.docs.map((doc) => ({
        id: doc.id,
        emoji: doc.data().emoji,
        name: doc.data().name,
        price: doc.data().price,
        isSold: doc.data().isSold,
        createdAt: doc.data().createdAt,
      })),
    );
  });
  return unsubscribe; // unsubscribe from the listener when the component is unmounting.
  // because it avoids memory leaks.
}, []);

Edit and delete product.

  1. Edit product
import { deleteDoc, doc, updateDoc } from "firebase/firestore";
const onEdit = () => {
  const docRef = doc(database, "products", id);
  updateDoc(docRef, {
    // updateDoc updates only the specified fields, the rest will stay the same.
    isSold: true,
  });
};
  1. Delete product

    it is quite simple, you only need to give the reference and use deleteDoc.

import { deleteDoc, doc, updateDoc } from "firebase/firestore";
const onDelete = () => {
  const docRef = doc(database, "products", id);
  deleteDoc(docRef);
};

Code of the Home.js screen

👍 Want to become a master in React Native? Check the React Native Course

Youtube GitHubDownload

Go back to Projects