Firebase 是 Google 提供的全面应用开发平台,包含认证、Firestore 数据库、实时数据库、云存储、云函数、托管和分析等服务。使用免费的 Spark 计划即可启动项目,Firestore 提供每天 50K 读取和 20K 写入。客户端 SDK 支持 Web、iOS 和 Android,Admin SDK 用于服务器端安全操作。Firebase Hosting 提供免费 SSL 和全球 CDN。
- Firebase 提供完整的后端即服务,包含认证、数据库、存储和托管
- Firestore 是推荐的数据库,支持复杂查询和离线同步
- 安全规则在服务器端执行,控制所有客户端访问
- Cloud Functions 处理服务器端逻辑、触发器和定时任务
- 免费 Spark 计划对原型开发和小型应用足够慷慨
- Admin SDK 用于服务器端操作,绕过安全规则
什么是 Firebase?
Firebase 是 Google 提供的应用开发平台,为开发者提供构建、改进和扩展应用所需的一系列后端服务和工具。Firebase 于 2011 年成立,2014 年被 Google 收购,现已发展成为一个全面的平台,包含超过 18 个产品,涵盖数据库、认证、存储、托管、分析、消息推送等。
Firebase 的核心优势在于它消除了管理服务器基础设施的需要。你可以专注于构建用户界面和业务逻辑,而 Firebase 负责后端的扩展、安全和维护。
项目设置与配置
开始使用 Firebase 需要创建项目、安装 SDK 并初始化配置。以下是完整的设置流程。
# 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 firebase在 Firebase 控制台创建项目后,你会获得一个配置对象。在你的应用中初始化 Firebase:
// 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 提供完整的用户认证系统,支持邮箱/密码、Google、GitHub、Twitter、Facebook 等多种登录方式。它处理令牌管理、会话持久化和安全性。
邮箱/密码认证
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 登录
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 数据库
Cloud Firestore 是 Firebase 推荐的 NoSQL 数据库,基于文档-集合模型。它支持实时同步、离线持久化、复杂查询和自动索引。数据组织为集合(collections)中的文档(documents),每个文档包含字段-值对。
CRUD 操作
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));查询与过滤
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)
);实时监听
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 安全规则
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";
}
}
}实时数据库 vs Firestore
Firebase 提供两个数据库产品。Realtime Database 是原始的 JSON 数据库,而 Firestore 是较新的文档数据库。以下是关键对比:
| 特性 | Firestore | Realtime Database |
|---|---|---|
| 数据模型 | 文档-集合 | JSON Tree |
| 查询 | 复合查询、索引 | 简单排序/过滤 |
| 离线支持 | Web、iOS、Android 全支持 | 仅 iOS、Android |
| 扩展性 | 自动,多区域 | 需要分片 |
| 定价 | 按操作计费 | 按带宽和存储 |
| 延迟 | 较低 | 极低 |
对于新项目,Google 推荐使用 Firestore。Realtime Database 适合需要极低延迟的简单数据同步场景,如在线状态指示器或多人游戏状态。
云存储 (Cloud Storage)
Firebase Cloud Storage 基于 Google Cloud Storage 构建,用于存储和提供用户生成的内容,如图片、视频和文件。它支持断点续传、进度监控和安全规则。
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);
});存储安全规则
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 是无服务器函数,在 Firebase 事件或 HTTPS 请求触发时运行。它们适合处理后端逻辑,如发送通知、处理支付、数据聚合和定时任务。
// 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();
}
);托管与部署
Firebase Hosting 提供快速、安全的静态和动态内容托管,包含免费 SSL、全球 CDN、原子部署和即时回滚。它支持单页应用、静态站点以及通过 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
Admin SDK 用于服务器端操作,它绕过安全规则并拥有完整的数据库和认证系统访问权限。用于 Node.js 后端、Cloud Functions 和服务器端渲染。
// 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"
});分析与性能监控
Firebase Analytics(基于 Google Analytics)提供免费、无限的应用分析,包含用户行为追踪、转化漏斗、受众细分和自定义事件。Performance Monitoring 自动追踪应用启动时间、网络请求延迟和屏幕渲染性能。
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 与 React / Next.js
Firebase 与 React 和 Next.js 集成非常好。在 React 中使用 hooks 管理认证状态和数据监听。在 Next.js 中,使用 Admin SDK 进行服务器端操作,客户端 SDK 用于实时功能。
React 认证 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 实时 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 服务器端操作
// 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 });
}安全最佳实践
Firebase 安全是应用安全的基础。以下是保护 Firebase 应用的关键实践:
- 永远不要依赖客户端验证 — 始终在安全规则中验证数据结构、类型和权限。客户端验证可以被绕过。
- 使用最小权限原则 — 默认拒绝所有访问,然后仅为需要的操作开放权限。不要使用 allow read, write: if true 。
- 保护 API 密钥 — Firebase API 密钥是公开的标识符,但应在 Google Cloud Console 中限制其使用范围(域名限制、API 限制)。
- 使用 App Check — Firebase App Check 验证请求来自你的合法应用,防止滥用。
- 验证自定义声明 — 在安全规则中使用 request.auth.token 检查角色和权限。
- 限制数据查询大小 — 在安全规则中使用 request.query.limit 防止客户端读取过多数据。
定价与免费额度
Firebase 提供两个计划:免费的 Spark 计划和按需付费的 Blaze 计划。Blaze 计划包含所有 Spark 免费额度。
| 服务 | Spark(免费) | Blaze(超出免费后) |
|---|---|---|
| Firestore 存储 | 1 GiB | $0.108/GiB |
| Firestore 读取 | 50K/天 | $0.036/100K |
| Firestore 写入 | 20K/天 | $0.108/100K |
| Cloud Storage | 5 GB | $0.026/GB |
| Cloud Functions | 125K/月 | $0.40/million |
| Hosting | 10 GB 带宽 | $0.15/GB |
| Authentication | 无限 | 无限(电话认证除外) |
| Analytics | 无限 | 无限 |
提示:Blaze 计划可以设置预算警报来防止意外费用。对于大多数原型和小型应用,免费额度完全足够。
Firebase 模拟器套件
Firebase 模拟器套件让你在本地运行 Firebase 服务进行开发和测试,无需连接到生产项目。它支持 Auth、Firestore、Realtime Database、Storage、Functions 和 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 替代方案
以下是 Firebase 与其他热门 BaaS 平台的对比:
| 特性 | Firebase | Supabase | PocketBase |
|---|---|---|---|
| 数据库 | Firestore (NoSQL) | PostgreSQL | SQLite |
| 托管 | Google Cloud | 云 / 自托管 | 自托管 |
| 实时 | 内置 | 内置 | SSE |
| 认证 | 多提供商 | 多提供商 | 邮箱 + OAuth |
| 函数 | Cloud Functions | Edge Functions | Go / JS hooks |
| 开源 | 否 | 是 | 是 |
| 免费额度 | 慷慨 | 慷慨 | 完全免费 |
常见问题
Firebase 包含哪些服务?
Firebase 包含 Authentication、Firestore、Realtime Database、Cloud Storage、Cloud Functions、Hosting、Analytics、Performance Monitoring、Crashlytics、Remote Config、Cloud Messaging 和 App Check 等超过 18 个服务。
Firestore 和 Realtime Database 有什么区别?
Firestore 是基于文档的 NoSQL 数据库,支持复杂查询和离线同步。Realtime Database 是 JSON 树结构,延迟更低但查询能力有限。新项目推荐 Firestore。
Firebase 免费吗?
Spark 计划免费,含 1 GiB Firestore 存储、每天 50K 读取、5 GB Cloud Storage 和无限 Analytics。Blaze 计划按需付费,超出免费额度后才收费。
如何设置认证?
在控制台启用认证提供商,安装 SDK,用 createUserWithEmailAndPassword 或 signInWithPopup 等方法。Firebase 自动处理令牌管理和会话。
安全规则如何工作?
安全规则在服务器端执行,用 match 语法定义路径和条件,检查 request.auth 验证身份,用 request.resource.data 验证数据。规则不可被客户端绕过。
可以与 React/Next.js 一起使用吗?
可以。React 中用客户端 SDK 配合 hooks 管理状态。Next.js 中 Server Components 用 Admin SDK,Client Components 用客户端 SDK。
Cloud Functions 什么时候用?
用于发送通知、处理支付、数据聚合、定时任务和第三方 API 集成等服务器端逻辑。
如何部署到生产环境?
用 Firebase CLI:firebase init 设置项目,firebase deploy 部署。用 --only hosting 或 --only functions 部署特定服务。Hosting 提供免费 SSL 和全球 CDN。
总结
Firebase 是构建全栈应用最快捷的方式之一。它消除了管理服务器基础设施的负担,让你专注于产品开发。从认证到数据库、存储到托管,Firebase 提供了构建现代应用所需的全部后端服务。免费的 Spark 计划对原型开发和小型应用足够慷慨,而 Blaze 计划的按需付费模式确保你只为实际使用付费。无论你是构建个人项目还是企业应用,Firebase 都是一个值得考虑的强大平台。