Examples
A small collection of working Firebase recipes: auth + Firestore CRUD with rules, Cloud Storage upload with signed URLs, Cloud Functions trigger, and Firebase Hosting with a custom rewrite. Each maps to a workflow most projects need by week two.
Five Firebase recipes wired together
EXAMPLE
// ===== 1) Auth + Firestore CRUD (web SDK v10) =====
import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged, signInWithEmailAndPassword } from 'firebase/auth';
import {
getFirestore, collection, doc, addDoc, updateDoc, deleteDoc,
query, where, orderBy, limit, onSnapshot, serverTimestamp,
} from 'firebase/firestore';
const app = initializeApp({/* config */});
const auth = getAuth(app);
const db = getFirestore(app);
await signInWithEmailAndPassword(auth, 'alice@example.com', 'hunter2');
const tasks = collection(db, 'tasks');
// Create
const ref = await addDoc(tasks, {
uid: auth.currentUser!.uid,
title: 'Buy milk',
done: false,
created_at: serverTimestamp(),
});
// Update
await updateDoc(doc(db, 'tasks', ref.id), { done: true });
// Delete
await deleteDoc(doc(db, 'tasks', ref.id));
// Real-time list of my open tasks
const q = query(tasks,
where('uid', '==', auth.currentUser!.uid),
where('done', '==', false),
orderBy('created_at', 'desc'),
limit(20));
onSnapshot(q, (snap) => snap.forEach((d) => console.log(d.id, d.data())));
// ===== 2) Firestore security rules — only the owner can read/write =====
// rules.firestore
// rules_version = '2';
// service cloud.firestore {
// match /databases/{database}/documents {
// match /tasks/{id} {
// allow read, update, delete: if request.auth != null
// && resource.data.uid == request.auth.uid;
// allow create: if request.auth != null
// && request.resource.data.uid == request.auth.uid;
// }
// }
// }
// ===== 3) Cloud Storage upload + signed download URL =====
import { getStorage, ref as sref, uploadBytes, getDownloadURL } from 'firebase/storage';
const storage = getStorage(app);
const file = (document.getElementById('file') as HTMLInputElement).files![0];
const path = \`users/${auth.currentUser!.uid}/receipts/${Date.now()}-${file.name}\`;
await uploadBytes(sref(storage, path), file, { contentType: file.type });
const url = await getDownloadURL(sref(storage, path));
console.log('uploaded to', url);
// ===== 4) Cloud Function (v2) triggered when a task completes =====
// functions/src/index.ts
// import { onDocumentUpdated } from 'firebase-functions/v2/firestore';
// import { logger } from 'firebase-functions';
// export const onTaskDone = onDocumentUpdated('tasks/{id}', async (event) => {
// const before = event.data?.before.data();
// const after = event.data?.after.data();
// if (!before?.done && after?.done) {
// logger.info({ id: event.params.id }, 'task completed');
// // send a push, write an audit row, etc.
// }
// });
// ===== 5) Firebase Hosting — SPA + serverless backend =====
// firebase.json
// {
// "hosting": {
// "public": "dist",
// "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
// "rewrites": [
// { "source": "/api/**", "function": "api" },
// { "source": "**", "destination": "/index.html" }
// ],
// "headers": [
// { "source": "**/*.@(js|css|woff2)",
// "headers": [{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }] }
// ]
// }
// }
// firebase deploy --only hosting,functions
Why it matters
Lock down Firestore with rules from day one and test them with the local emulator. A rule typo today is an open database tomorrow — the emulator runs your rules unit-tested against fake requests, so you catch \"allow read: if true\" before it ships, when the cost of fixing it is zero.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…