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
- I'm not using
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); } }); }, []); ...