Firebase is Google's comprehensive app development platform providing Authentication, Firestore database, Realtime Database, Cloud Storage, Cloud Functions, Hosting, and Analytics. Start with the free Spark plan offering 50K Firestore reads and 20K writes per day. Client SDKs support Web, iOS, and Android, while the Admin SDK handles secure server-side operations. Firebase Hosting includes free SSL and a global CDN.
- Firebase provides a complete Backend-as-a-Service with auth, database, storage, and hosting
- Firestore is the recommended database with complex queries and offline sync
- Security rules execute server-side and control all client access
- Cloud Functions handle server-side logic, triggers, and scheduled tasks
- The free Spark plan is generous enough for prototypes and small apps
- Admin SDK is used for server-side operations, bypassing security rules
What Is Firebase?
Firebase is an application development platform by Google that provides developers with a suite of backend services and tools to build, improve, and scale applications. Founded in 2011 and acquired by Google in 2014, Firebase has grown into a comprehensive platform with over 18 products covering databases, authentication, storage, hosting, analytics, messaging, and more.
The core advantage of Firebase is that it eliminates the need to manage server infrastructure. You focus on building your user interface and business logic while Firebase handles backend scaling, security, and maintenance.
Project Setup & Configuration
Getting started with Firebase requires creating a project, installing the SDK, and initializing the configuration. Here is the complete setup process.
# Install Firebase CLI globally
npm install -g firebase-tools
# Login to Firebase
firebase login
# Initialize a new project
firebase init
# Install Firebase SDK in your project
npm install firebaseAfter creating a project in the Firebase Console, you receive a configuration object. Initialize Firebase in your application:
// src/lib/firebase.ts
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
import { getStorage } from "firebase/storage";
const firebaseConfig = {
apiKey: "AIzaSyD...",
authDomain: "myapp.firebaseapp.com",
projectId: "myapp-12345",
storageBucket: "myapp-12345.appspot.com",
messagingSenderId: "123456789",
appId: "1:123456789:web:abc123",
measurementId: "G-XXXXXXX"
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const db = getFirestore(app);
export const storage = getStorage(app);Authentication
Firebase Authentication provides a complete user authentication system supporting email/password, Google, GitHub, Twitter, Facebook, and more. It handles token management, session persistence, and security.
Email/Password Authentication
import { getAuth, createUserWithEmailAndPassword,
signInWithEmailAndPassword, signOut,
onAuthStateChanged, sendPasswordResetEmail,
sendEmailVerification } from "firebase/auth";
const auth = getAuth();
// Register a new user
async function register(email: string, password: string) {
const userCredential = await createUserWithEmailAndPassword(
auth, email, password
);
// Send email verification
await sendEmailVerification(userCredential.user);
return userCredential.user;
}
// Sign in existing user
async function login(email: string, password: string) {
const userCredential = await signInWithEmailAndPassword(
auth, email, password
);
return userCredential.user;
}
// Listen for auth state changes
onAuthStateChanged(auth, (user) => {
if (user) {
console.log("Signed in:", user.uid);
} else {
console.log("Signed out");
}
});
// Sign out
await signOut(auth);
// Password reset
await sendPasswordResetEmail(auth, "user@example.com");Google & GitHub OAuth Sign-In
import { GoogleAuthProvider, GithubAuthProvider,
signInWithPopup, signInWithRedirect } from "firebase/auth";
// Google Sign-In
async function signInWithGoogle() {
const provider = new GoogleAuthProvider();
provider.addScope("profile");
provider.addScope("email");
const result = await signInWithPopup(auth, provider);
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential?.accessToken;
return result.user;
}
// GitHub Sign-In
async function signInWithGitHub() {
const provider = new GithubAuthProvider();
provider.addScope("repo");
const result = await signInWithPopup(auth, provider);
return result.user;
}Cloud Firestore Database
Cloud Firestore is Firebase's recommended NoSQL database built on a document-collection model. It supports real-time sync, offline persistence, complex queries, and automatic indexing. Data is organized as documents within collections, where each document contains field-value pairs.
CRUD Operations
import { collection, doc, addDoc, setDoc, getDoc,
getDocs, updateDoc, deleteDoc, serverTimestamp,
arrayUnion, increment } from "firebase/firestore";
// CREATE - Add a document with auto-generated ID
const docRef = await addDoc(collection(db, "posts"), {
title: "Getting Started with Firebase",
content: "Firebase is a powerful platform...",
author: "jane_doe",
tags: ["firebase", "tutorial"],
likes: 0,
createdAt: serverTimestamp()
});
console.log("Document ID:", docRef.id);
// CREATE - Set a document with a specific ID
await setDoc(doc(db, "users", "user123"), {
name: "Jane Doe",
email: "jane@example.com",
role: "admin"
});
// READ - Get a single document
const docSnap = await getDoc(doc(db, "posts", docRef.id));
if (docSnap.exists()) {
console.log("Data:", docSnap.data());
}
// READ - Get all documents in a collection
const querySnapshot = await getDocs(collection(db, "posts"));
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
});
// UPDATE - Update specific fields
await updateDoc(doc(db, "posts", docRef.id), {
title: "Updated Title",
likes: increment(1),
tags: arrayUnion("updated")
});
// DELETE
await deleteDoc(doc(db, "posts", docRef.id));Queries & Filtering
import { query, where, orderBy, limit, startAfter,
getDocs } from "firebase/firestore";
// Simple query with filter
const q1 = query(
collection(db, "posts"),
where("author", "==", "jane_doe"),
where("likes", ">=", 10),
orderBy("likes", "desc"),
limit(20)
);
const snapshot = await getDocs(q1);
// Array contains query
const q2 = query(
collection(db, "posts"),
where("tags", "array-contains", "firebase")
);
// Pagination with cursors
const first = query(
collection(db, "posts"),
orderBy("createdAt", "desc"),
limit(10)
);
const firstPage = await getDocs(first);
const lastDoc = firstPage.docs[firstPage.docs.length - 1];
const next = query(
collection(db, "posts"),
orderBy("createdAt", "desc"),
startAfter(lastDoc),
limit(10)
);Real-Time Listeners
import { onSnapshot } from "firebase/firestore";
// Listen to a single document
const unsubDoc = onSnapshot(
doc(db, "posts", "post123"),
(doc) => {
console.log("Current data:", doc.data());
}
);
// Listen to a query
const unsubQuery = onSnapshot(
query(collection(db, "posts"),
where("author", "==", "jane_doe")),
(snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === "added") {
console.log("New post:", change.doc.data());
}
if (change.type === "modified") {
console.log("Updated:", change.doc.data());
}
if (change.type === "removed") {
console.log("Removed:", change.doc.id);
}
});
}
);
// Unsubscribe when done
unsubDoc();
unsubQuery();Firestore Security Rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Users can read/write their own profile
match /users/{userId} {
allow read: if request.auth != null;
allow write: if request.auth.uid == userId;
}
// Posts: anyone can read, only author can write
match /posts/{postId} {
allow read: if true;
allow create: if request.auth != null
&& request.resource.data.author == request.auth.uid
&& request.resource.data.title is string
&& request.resource.data.title.size() <= 200;
allow update: if request.auth.uid ==
resource.data.author;
allow delete: if request.auth.uid ==
resource.data.author;
}
// Helper function for admin check
function isAdmin() {
return request.auth != null
&& get(/databases/$(database)/documents/
users/$(request.auth.uid)).data.role == "admin";
}
}
}Realtime Database vs Firestore
Firebase offers two database products. Realtime Database is the original JSON database, and Firestore is the newer document database. Here is a key comparison:
| Feature | Firestore | Realtime Database |
|---|---|---|
| Data Model | Document-Collection | JSON Tree |
| Queries | Compound queries, indexing | Simple sort/filter |
| Offline | Web, iOS, Android | iOS, Android only |
| Scaling | Automatic, multi-region | Requires sharding |
| Pricing | Per operation | Bandwidth + storage |
| Latency | Low | Very low |
For new projects, Google recommends Firestore. Realtime Database is suitable for scenarios requiring extremely low-latency data synchronization, such as presence indicators or multiplayer game state.
Cloud Storage
Firebase Cloud Storage is built on Google Cloud Storage for storing and serving user-generated content like images, videos, and files. It supports resumable uploads, progress monitoring, and security rules.
import { ref, uploadBytes, uploadBytesResumable,
getDownloadURL, deleteObject,
listAll } from "firebase/storage";
// Upload a file
async function uploadFile(file: File, path: string) {
const storageRef = ref(storage, path);
const snapshot = await uploadBytes(storageRef, file);
const url = await getDownloadURL(snapshot.ref);
return url;
}
// Upload with progress tracking
function uploadWithProgress(file: File, path: string) {
const storageRef = ref(storage, path);
const uploadTask = uploadBytesResumable(storageRef, file);
uploadTask.on("state_changed",
(snapshot) => {
const progress = (snapshot.bytesTransferred /
snapshot.totalBytes) * 100;
console.log("Upload:", progress + "% done");
},
(error) => console.error("Upload failed:", error),
async () => {
const url = await getDownloadURL(
uploadTask.snapshot.ref
);
console.log("Download URL:", url);
}
);
}
// Download URL for a file
const url = await getDownloadURL(
ref(storage, "images/photo.jpg")
);
// Delete a file
await deleteObject(ref(storage, "images/photo.jpg"));
// List all files in a directory
const result = await listAll(ref(storage, "images"));
result.items.forEach((itemRef) => {
console.log(itemRef.fullPath);
});Storage Security Rules
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// Users can upload to their own folder
match /users/{userId}/{allPaths=**} {
allow read: if request.auth != null;
allow write: if request.auth.uid == userId
&& request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType
.matches('image/.*');
}
// Public read for published content
match /public/{allPaths=**} {
allow read: if true;
allow write: if request.auth != null;
}
}
}Cloud Functions
Firebase Cloud Functions are serverless functions that run in response to Firebase events or HTTPS requests. They are ideal for backend logic like sending notifications, processing payments, data aggregation, and scheduled tasks.
// functions/src/index.ts
import { onRequest } from "firebase-functions/v2/https";
import { onDocumentCreated } from "firebase-functions/v2/firestore";
import { onSchedule } from "firebase-functions/v2/scheduler";
import { getFirestore } from "firebase-admin/firestore";
import { initializeApp } from "firebase-admin/app";
initializeApp();
const db = getFirestore();
// HTTPS function
export const helloWorld = onRequest((req, res) => {
res.json({ message: "Hello from Firebase!" });
});
// Firestore trigger: on new post created
export const onPostCreated = onDocumentCreated(
"posts/{postId}",
async (event) => {
const data = event.data?.data();
if (!data) return;
await db.doc("users/" + data.author).update({
postCount: FieldValue.increment(1)
});
}
);
// Scheduled function: daily cleanup
export const dailyCleanup = onSchedule("every day 02:00",
async () => {
const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - 30);
const old = await db.collection("logs")
.where("createdAt", "<", cutoff).get();
const batch = db.batch();
old.docs.forEach((d) => batch.delete(d.ref));
await batch.commit();
}
);Hosting & Deployment
Firebase Hosting provides fast, secure hosting for static and dynamic content with free SSL, global CDN, atomic deploys, and instant rollback. It supports single-page apps, static sites, and server-side rendering via Cloud Functions.
# firebase.json configuration
{
"hosting": {
"public": "build",
"ignore": ["firebase.json", "**/node_modules/**"],
"rewrites": [
{ "source": "/api/**", "function": "api" },
{ "source": "**", "destination": "/index.html" }
],
"headers": [{
"source": "**/*.@(js|css)",
"headers": [{ "key": "Cache-Control",
"value": "max-age=31536000" }]
}]
}
}
# Deploy commands
firebase deploy # deploy all
firebase deploy --only hosting # hosting only
firebase hosting:channel:deploy staging # preview
firebase hosting:rollback # rollbackFirebase Admin SDK
The Admin SDK is for server-side operations. It bypasses security rules and has full access to the database and authentication system. Use it in Node.js backends, Cloud Functions, and server-side rendering.
// Server-side: Admin SDK setup
import { initializeApp, cert } from "firebase-admin/app";
import { getFirestore } from "firebase-admin/firestore";
import { getAuth } from "firebase-admin/auth";
const app = initializeApp({
credential: cert({
projectId: "myapp-12345",
clientEmail: "firebase-adminsdk@myapp.iam...",
privateKey: process.env.FIREBASE_PRIVATE_KEY
})
});
const db = getFirestore();
const auth = getAuth();
// Admin operations bypass security rules
const users = await auth.listUsers(100);
users.users.forEach((user) => {
console.log(user.uid, user.email);
});
// Verify ID tokens from client
async function verifyToken(idToken: string) {
const decoded = await auth.verifyIdToken(idToken);
return decoded; // { uid, email, ... }
}
// Set custom claims for roles
await auth.setCustomUserClaims("user123", {
admin: true,
role: "editor"
});Analytics & Performance Monitoring
Firebase Analytics (powered by Google Analytics) provides free, unlimited app analytics with user behavior tracking, conversion funnels, audience segmentation, and custom events. Performance Monitoring automatically tracks app start time, network request latency, and screen rendering performance.
import { getAnalytics, logEvent,
setUserProperties } from "firebase/analytics";
import { getPerformance, trace } from "firebase/performance";
// Initialize Analytics
const analytics = getAnalytics();
// Log custom events
logEvent(analytics, "tool_used", {
tool_name: "json_formatter",
input_size: 1024
});
// Log purchase event
logEvent(analytics, "purchase", {
currency: "USD",
value: 9.99,
items: [{ item_name: "Pro Plan" }]
});
// Set user properties for segmentation
setUserProperties(analytics, {
plan: "pro",
preferred_language: "en"
});
// Performance Monitoring - custom trace
const perf = getPerformance();
const t = trace(perf, "data_load");
t.start();
// ... perform operation
t.putAttribute("data_source", "firestore");
t.putMetric("item_count", 42);
t.stop();Firebase with React & Next.js
Firebase integrates well with React and Next.js. Use React hooks to manage auth state and data listeners. In Next.js, use the Admin SDK for server-side operations and the client SDK for real-time features.
React Auth Hook
// hooks/useAuth.ts
import { useState, useEffect } from "react";
import { onAuthStateChanged, User } from "firebase/auth";
import { auth } from "../lib/firebase";
export function useAuth() {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
setUser(user);
setLoading(false);
});
return () => unsub();
}, []);
return { user, loading };
}React Firestore Real-Time Hook
// hooks/useCollection.ts
import { useState, useEffect } from "react";
import { collection, query, onSnapshot,
QueryConstraint } from "firebase/firestore";
import { db } from "../lib/firebase";
export function useCollection<T>(
path: string,
constraints: QueryConstraint[] = []
) {
const [data, setData] = useState<T[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const q = query(collection(db, path),
...constraints);
const unsub = onSnapshot(q, (snap) => {
const docs = snap.docs.map((d) => ({
id: d.id,
...d.data()
})) as T[];
setData(docs);
setLoading(false);
});
return () => unsub();
}, [path]);
return { data, loading };
}Next.js Server-Side with Admin SDK
// app/api/posts/route.ts (Next.js App Router)
import { getFirestore } from "firebase-admin/firestore";
import { getAuth } from "firebase-admin/auth";
import { NextRequest, NextResponse } from "next/server";
const db = getFirestore();
export async function GET(req: NextRequest) {
// Verify auth token from header
const token = req.headers
.get("Authorization")?.split("Bearer ")[1];
if (!token) {
return NextResponse.json(
{ error: "Unauthorized" }, { status: 401 }
);
}
const decoded = await getAuth().verifyIdToken(token);
// Fetch user posts server-side
const snap = await db.collection("posts")
.where("author", "==", decoded.uid)
.orderBy("createdAt", "desc")
.limit(20)
.get();
const posts = snap.docs.map((d) => ({
id: d.id,
...d.data()
}));
return NextResponse.json({ posts });
}Security Best Practices
Firebase security is foundational to application security. Here are key practices for securing your Firebase application:
- Never rely on client-side validation alone — Always validate data structure, types, and permissions in security rules. Client-side validation can be bypassed.
- Use the principle of least privilege — Default deny all access, then only open permissions for needed operations. Never use allow read, write: if true in production.
- Protect API keys — Firebase API keys are public identifiers, but restrict their usage scope in Google Cloud Console (domain restrictions, API restrictions).
- Enable App Check — Firebase App Check verifies that requests come from your legitimate app, preventing abuse.
- Validate custom claims — Use request.auth.token in security rules to check roles and permissions.
- Limit query sizes — Use request.query.limit in security rules to prevent clients from reading excessive data.
Pricing & Free Tier
Firebase offers two plans: the free Spark plan and the pay-as-you-go Blaze plan. The Blaze plan includes all Spark free tier allowances.
| Service | Spark (Free) | Blaze (Beyond Free) |
|---|---|---|
| Firestore Storage | 1 GiB | $0.108/GiB |
| Firestore Reads | 50K/day | $0.036/100K |
| Firestore Writes | 20K/day | $0.108/100K |
| Cloud Storage | 5 GB | $0.026/GB |
| Cloud Functions | 125K/mo | $0.40/million |
| Hosting | 10 GB bandwidth | $0.15/GB |
| Authentication | Unlimited | Unlimited (except phone auth) |
| Analytics | Unlimited | Unlimited |
Tip: The Blaze plan supports budget alerts to prevent unexpected charges. For most prototypes and small apps, the free tier is more than sufficient.
Firebase Emulator Suite
The Firebase Emulator Suite lets you run Firebase services locally for development and testing without connecting to a production project. It supports Auth, Firestore, Realtime Database, Storage, Functions, and Hosting.
# Install and start emulators
firebase init emulators
firebase emulators:start
# Default ports: Auth :9099, Firestore :8080,
# Functions :5001, Storage :9199, UI :4000
// Connect app to emulators in development
import { connectAuthEmulator } from "firebase/auth";
import { connectFirestoreEmulator } from "firebase/firestore";
if (process.env.NODE_ENV === "development") {
connectAuthEmulator(auth, "http://localhost:9099");
connectFirestoreEmulator(db, "localhost", 8080);
}Firebase vs Alternatives
Here is how Firebase compares with other popular BaaS platforms:
| Feature | Firebase | Supabase | PocketBase |
|---|---|---|---|
| Database | Firestore (NoSQL) | PostgreSQL | SQLite |
| Hosting | Google Cloud | Cloud / Self-host | Self-hosted |
| Realtime | Built-in | Built-in | SSE |
| Auth | Multi-provider | Multi-provider | Email + OAuth |
| Functions | Cloud Functions | Edge Functions | Go / JS hooks |
| Open Source | No | Yes | Yes |
| Free Tier | Generous | Generous | Fully free |
Frequently Asked Questions
What services does Firebase include?
Firebase includes Authentication, Firestore, Realtime Database, Cloud Storage, Cloud Functions, Hosting, Analytics, Performance Monitoring, Crashlytics, Remote Config, Cloud Messaging, App Check, and over 18 services total.
What is the difference between Firestore and Realtime Database?
Firestore is a document-based NoSQL database with complex queries and offline sync. Realtime Database is a JSON tree with lower latency but limited querying. Firestore is recommended for new projects.
Is Firebase free to use?
The Spark plan is free with 1 GiB Firestore storage, 50K reads per day, 5 GB Cloud Storage, and unlimited Analytics. The Blaze plan is pay-as-you-go, charging only beyond free allowances.
How do I set up Authentication?
Enable providers in the Console, install the SDK, and use createUserWithEmailAndPassword or signInWithPopup. Firebase handles token management and sessions automatically.
How do security rules work?
Rules execute server-side using match syntax for paths and conditions. Check request.auth for identity and request.resource.data for validation. Rules cannot be bypassed from client SDKs.
Can I use Firebase with React and Next.js?
Yes. In React, use the client SDK with hooks. In Next.js, use the Admin SDK in Server Components and API Routes, and the client SDK in Client Components for real-time features.
When should I use Cloud Functions?
Use them for server-side logic like notifications, payment processing, data aggregation, scheduled tasks, and third-party API integrations.
How do I deploy to production?
Use the Firebase CLI: firebase init to set up, firebase deploy to deploy. Use --only hosting or --only functions for specific services. Hosting provides free SSL and global CDN.
Conclusion
Firebase is one of the fastest ways to build full-stack applications. It eliminates the burden of managing server infrastructure so you can focus on product development. From authentication to database, storage to hosting, Firebase provides all the backend services needed for modern applications. The free Spark plan is generous enough for prototypes and small apps, while the Blaze plan's pay-as-you-go model ensures you only pay for what you use. Whether you are building a personal project or an enterprise application, Firebase is a powerful platform worth considering.