2022-04-08

Firebase snippets for CRUD and Auth (version 9)

Collection of Firebase snippets for my future use

  • posts

    • title content owner createdAt modifiedAt isPublished
  • users

    • email password

Get started

  • Go to Firebase console
  • Add project
  • Create database from Firestore Database (Cloud Firestore) menu on the left
    • I'm not using Realtime Database here
    • I can still listen for realtime updates with Firestore Database

Prep/config

npm i firebase
// firebase.js import { initializeApp } from "firebase/app"; import { getFirestore } from "firebase/firestore"; import { getAuth } from "firebase/auth"; const firebaseConfig = { apiKey: "", authDomain: "", projectId: "", storageBucket: "", messagingSenderId: "", appId: "", }; const app = initializeApp(firebaseConfig); const db = getFirestore(app); const auth = getAuth(app); export { db, auth };

CRUD

// import config from above import { db } from "./firebase"; // VS Code will auto import if you start typing import { collection, doc, setDoc, serverTimestamp, getDoc, onSnapshot, deleteDoc, query, where, orderBy, limit } from "firebase/firestore";

Create - setDoc

// Document ID is auto-generated by Firebase const docRef = doc(collection(db, "posts")); await setDoc(docRef, { title, content, createdAt: serverTimestamp(), modifiedAt: serverTimestamp(), });

If your field needs to be unique, set the value as document ID

// Document ID is set with given string await setDoc(doc(db, "users", "set-the-userId-123"), { email: "", password: "", });
// Document ID is set with given string await setDoc( doc(db, "users", "set-the-userId-123"), // Convert Firebase custom UserImpl object -> JavaScript object JSON.parse(JSON.stringify(userCredentials.user)) );

Read - getDoc (single document)

const docRef = doc(db, "users", post.owner); const docSnap = await getDoc(docRef); if (docSnap.exists) { console.log(docSnap.data()); } else { console.log("No such document!"); }

Read - getDocs (not realtime)

const colRef = collection(db, "posts"); const snapshot = await getDocs(colRef); snapshot.docs.map((doc) => { console.log(doc.data()); return doc.data(); });

Read - onSnapshot (realtime updates)

// Without query const colRef = collection(db, "posts"); onSnapshot(colRef, (snap) => { snap.docs.forEach((doc) => { console.log(doc.id); console.log(doc.data()); }); });
// Using query const colRef = collection(db, "posts"); const q = query(colRef, where("isPublished", "==", "true"), orderBy("createdAt", "desc"), limit(10)); onSnapshot(q, (snap) => { snap.docs.forEach((doc) => { console.log(doc.id); console.log(doc.data()); }); });
// Mixed with some react code import { useState, useEffect } from "react"; export const PostList = () => { const [posts, setPosts] = useState([]); useEffect(() => { const docRef = collection(db, "posts"); const q = query(docRef, orderBy("createdAt", "desc")); const unsubscribe = onSnapshot(q, (snap) => { setPosts( snap.docs.map((doc) => ({ ...doc.data(), id: doc.id, })) ); }); return () => unsubscribe(); }, []); return ( <div> {posts && posts.map((post) => ( {post.title} ))} </div> ); }

Update - setDoc

const docRef = doc(db, "posts", post.id); await setDoc(docRef, { title: newTitle, content: newContent, modifiedAt: serverTimestamp(), }, { merge: true } );

Delete - deleteDoc

const docRef = doc(db, "posts", post.id); await deleteDoc(docRef);

Auth

import { db, auth } from "./firebase"; import { onAuthStateChanged, createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut, sendPasswordResetEmail, AuthErrorCodes, } from "firebase/auth";

Signup

// Create user to Firebase `Authentication` const userCredentials = await createUserWithEmailAndPassword(auth, "email", "password"); console.log(userCredentials.user); // Add created user to Firebase `Firestore Database` await setDoc( doc(db, "users", userCredentials.user.uid), // Convert Firebase custom UserImpl object -> JavaScript object JSON.parse(JSON.stringify(userCredentials.user)) )

Login

const userCredentials = await signInWithEmailAndPassword(auth, "email", "password"); console.log(userCredentials.user);

Logout

await signOut(auth);

Password resetg

await sendPasswordResetEmail(auth, "email");

Error handling

try { const userCredentials = await signInWithEmailAndPassword(auth, "email", "password"); } catch (error) { if (error.code == AuthErrorCodes.USER_DELETED) { console.log("user-not-found"); } else if (error.code == AuthErrorCodes.INVALID_PASSWORD) { console.log("wrong-password"); } ... }

Setting an observer on the Auth object - onAuthStateChanged

// Mixed with some react code // UerContext.js export const UserProvider = ({ children }) => { const [user, setUser] = useState(null); useEffect(() => { onAuthStateChanged(auth, (user) => { if (user) { console.log("onAuthStateChanged: " + user.email); setUser(user); } else { console.log("onAuthStateChanged: no user"); setUser(null); } }); }, []); ...