Firebase 全栈利器:认证、数据库与云函数

FreeGuideOnline 最新 2026-06-12

认识 Firebase:现代全栈开发的新范式

Firebase 是 Google 推出的一站式后端即服务(BaaS)平台,它把复杂的服务器搭建、运维和扩展工作全部抽象为开箱即用的 API。无论你是独立开发者还是小团队,Firebase 都能让你在数小时内将应用从想法变为上线产品。本教程将聚焦三大核心能力:身份认证、实时云数据库、无服务器云函数,带你彻底告别自己写后端接口的日子。

在传统开发中,我们需要先搭建服务器环境,编写用户注册登录逻辑,设计数据库模型,部署 API,还得时刻担心服务器宕机。Firebase 直接将上述环节替换为:

  • 认证系统:一行代码集成邮箱密码、Google 登录、匿名登录等多种方式。
  • Firestore 数据库:实时同步的 NoSQL 文档数据库,无需手写 SQL。
  • Cloud Functions:由事件驱动的无服务器函数,在数据库变动、用户注册时自动执行后端逻辑。

三者结合,形成了一套完整的全栈开发闭环。下面你将从零开始,亲手构建一个具备用户登录、数据存储与自动触发逻辑的笔记应用。


环境准备与项目初始化

创建 Firebase 项目

  1. 前往 Firebase 控制台,使用 Google 账号登录。
  2. 点击“添加项目”,输入项目名称(如 my-notes-app),按照向导完成创建。
  3. 在项目概览页,点击“Web”图标(</>)注册一个 Web 应用。注册后会获得一段配置代码,包含 apiKeyprojectId 等,稍后会用到。

安装与配置 Firebase SDK

在你的前端项目根目录下安装 Firebase:

npm install firebase

然后新建 src/firebase/config.js,填入从控制台获取的配置:

import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { getFunctions } from 'firebase/functions';

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_PROJECT.firebaseapp.com",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_PROJECT.appspot.com",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID"
};

const app = initializeApp(firebaseConfig);

export const auth = getAuth(app);
export const db = getFirestore(app);
export const functions = getFunctions(app);

这样,认证、数据库、云函数三个服务的入口就统一导出了。所有后续操作都将基于 authdbfunctions 这几个实例。


Firebase 认证:五分钟构建用户系统

开启登录方式

在 Firebase 控制台左侧菜单进入“构建” → “Authentication”,点击“开始”,然后在“登录方式”标签中启用你需要的提供商。这里我们开启电子邮件/密码Google登录。

实现邮箱密码注册与登录

注册新用户并自动登录的代码极其简洁:

import { createUserWithEmailAndPassword } from 'firebase/auth';
import { auth } from './firebase/config';

const register = async (email, password) => {
  try {
    const userCredential = await createUserWithEmailAndPassword(auth, email, password);
    console.log('注册成功', userCredential.user);
    return userCredential.user;
  } catch (error) {
    console.error('注册失败', error.message);
  }
};

已有用户登录:

import { signInWithEmailAndPassword } from 'firebase/auth';

const login = async (email, password) => {
  try {
    const userCredential = await signInWithEmailAndPassword(auth, email, password);
    console.log('登录成功', userCredential.user);
  } catch (error) {
    console.error('登录失败', error.message);
  }
};

监听用户状态变化

Firebase 会自动持久化登录状状态,页面刷新后仍然有效。我们可以通过监听器获取当前用户:

import { onAuthStateChanged } from 'firebase/auth';

onAuthStateChanged(auth, (user) => {
  if (user) {
    // 用户已登录,显示主界面
    console.log('当前用户 UID:', user.uid);
  } else {
    // 用户未登录,跳转到登录页
    console.log('未登录');
  }
});

集成 Google 一键登录

只需几行代码,无需处理 OAuth 流程细节:

import { GoogleAuthProvider, signInWithPopup } from 'firebase/auth';

const signInWithGoogle = async () => {
  const provider = new GoogleAuthProvider();
  try {
    const result = await signInWithPopup(auth, provider);
    console.log('Google 登录成功', result.user);
  } catch (error) {
    console.error(error);
  }
};

至此,一个多登录方式的用户系统已经完成,你甚至无需关心 token 管理、密码加密等问题。


Cloud Firestore:实时文档数据库

Firestore 数据结构:集合与文档

Firestore 采用集合(collection)→ 文档(document)→ 字段(field)的层次结构。与关系型数据库不同,它没有固定的表结构,每个文档可以拥有不同的字段,非常适合快速迭代。

例如,我们要存储用户的笔记,可以设计一个 notes 集合,每个文档包含 titlecontentuserIdupdatedAt 等字段。

写入数据并关联用户

添加一条新笔记,并自动绑定当前登录用户的 UID:

import { collection, addDoc, serverTimestamp } from 'firebase/firestore';
import { db, auth } from './firebase/config';

const createNote = async (title, content) => {
  const user = auth.currentUser;
  if (!user) return alert('请先登录');

  await addDoc(collection(db, 'notes'), {
    title: title,
    content: content,
    userId: user.uid,
    createdAt: serverTimestamp(),
    updatedAt: serverTimestamp()
  });
};

serverTimestamp() 使用 Firebase 服务器时间,避免了客户端时间不同步的问题。

实时查询当前用户的笔记

Firestore 的强大之处在于可以监听数据变化,任何增删改都会立即推送到前端。使用 where 过滤当前用户,并按更新时间排序:

import { query, collection, where, orderBy, onSnapshot } from 'firebase/firestore';

const listenNotes = () => {
  const user = auth.currentUser;
  if (!user) return;

  const q = query(
    collection(db, 'notes'),
    where('userId', '==', user.uid),
    orderBy('updatedAt', 'desc')
  );

  const unsubscribe = onSnapshot(q, (snapshot) => {
    const notes = [];
    snapshot.forEach((doc) => {
      notes.push({ id: doc.id, ...doc.data() });
    });
    console.log('当前笔记列表:', notes);
    // 这里更新你的界面状态
  });

  // 返回取消监听的函数,防止内存泄漏
  return unsubscribe;
};

当用户在另一设备修改笔记时,界面会毫秒级自动更新。这就是 Firebase 的实时同步能力。

更新和删除数据

import { doc, updateDoc, deleteDoc } from 'firebase/firestore';

const updateNote = async (noteId, newData) => {
  const noteRef = doc(db, 'notes', noteId);
  await updateDoc(noteRef, { ...newData, updatedAt: serverTimestamp() });
};

const deleteNote = async (noteId) => {
  await deleteDoc(doc(db, 'notes', noteId));
};

结合监听器,任何操作都会立刻反映在所有设备上。


Cloud Functions:让后端逻辑跑在云端

函数触发器的运行机制

当仅使用客户端 SDK 时,某些操作不够安全(如所有人可读写数据库)或需要执行敏感任务(发送邮件、支付处理)。Cloud Functions 允许你在 Firebase 服务器上运行自定义逻辑,并对事件做出响应。函数可以基于多种触发器运行,最常用的是:

  • Firestore 触发器:文档创建、更新、删除时触发。
  • Auth 触发器:用户注册、登录或删除时触发。
  • HTTP 触发器:直接通过 URL 调用,类似传统 API。

部署你的第一个云函数

安装 Firebase CLI 并初始化

npm install -g firebase-tools
firebase login
firebase init functions
# 选择已有的 Firebase 项目
# 语言选择 JavaScript 或 TypeScript
# 安装依赖

初始化后会在项目根目录生成 functions/ 文件夹,主要逻辑写在 functions/index.js 中。

编写一个 Firestore 触发器:自动更新统计字段

假设每次用户创建或删除笔记时,我们需要更新用户文档中的笔记数量。首先在 Firestore 中建立一个 users/{uid} 文档,包含 notesCount 字段。

functions/index.js 中:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

exports.onNoteWritten = functions.firestore
  .document('notes/{noteId}')
  .onWrite(async (change, context) => {
    const noteId = context.params.noteId;
    const userId = change.after.exists 
      ? change.after.data().userId 
      : change.before.data().userId;

    if (!userId) return null;

    const notesRef = admin.firestore().collection('notes');
    const snapshot = await notesRef.where('userId', '==', userId).get();
    const count = snapshot.size;

    return admin.firestore().collection('users').doc(userId).update({
      notesCount: count
    });
  });

解释:onWrite 代表任何写操作(创建、更新、删除)都会触发。函数内部使用 Admin SDK 统计该用户的笔记总数,并更新 users 集合中的统计字段。

部署函数

在终端执行:

firebase deploy --only functions

部署完成之后,函数自动运行,无需管理服务器。现在,当你在前端创建一条笔记时,notesCount 字段会立刻被更新。

使用认证触发器:新用户注册时创建用户文档

exports.createUserProfile = functions.auth.user().onCreate((user) => {
  const uid = user.uid;
  const email = user.email;
  return admin.firestore().collection('users').doc(uid).set({
    email,
    createdAt: admin.firestore.FieldValue.serverTimestamp(),
    notesCount: 0
  });
});

用户注册成功瞬间,系统自动在 users 集合中插入一条文档,无需前端额外代码。

编写 HTTP 函数作为公开 API

有时你需要暴露一个端点供外部服务调用,比如一个公开的搜索接口:

exports.searchPublicNotes = functions.https.onRequest(async (req, res) => {
  // 仅允许 GET 请求
  if (req.method !== 'GET') {
    return res.status(405).send('Method Not Allowed');
  }
  
  const q = req.query.q;
  if (!q) return res.status(400).send('Missing query parameter q');
  
  const notesRef = admin.firestore().collection('notes');
  // 注意:Firestore 不支持全文搜索,这里仅为示例
  const snapshot = await notesRef.where('title', '==', q).limit(10).get();
  
  const results = [];
  snapshot.forEach(doc => results.push(doc.data()));
  res.json({ results });
});

部署后会提供一个公网 URL:https://your-project.web.app/searchPublicNotes?q=hello ,你可将其视为传统的 REST API。


安全规则:保护你的数据

为什么需要安全规则

截至目前,我们的 Firestore 数据库是“测试模式”,任何人可读可写,这在生产环境中极度危险。必须使用 Firebase 安全规则(Security Rules)限制数据访问。

在控制台“Firestore Database” → “规则”中编写规则。一个典型的笔记应用规则如下:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // 用户只能读写自己的笔记
    match /notes/{noteId} {
      allow read, write: if request.auth != null 
                         && resource.data.userId == request.auth.uid;
    }
    // 用户只能读写自己的用户文档
    match /users/{userId} {
      allow read, write: if request.auth != null 
                         && request.auth.uid == userId;
    }
  }
}

规则利用 request.auth 对象校验身份,resource.data 代表请求的文档数据。发布规则后,即使客户端代码被篡改,攻击者也无法读写他人数据。

结合 Cloud Functions 提升安全性

对于需要突破上述限制的特权操作(如统计笔记总数),我们将其放在云函数中用 Admin SDK 执行,因为 Admin SDK 绕过所有安全规则。这样客户端代码永远无法直接修改 notesCount 字段,保证了数据完整性。


构建全栈笔记应用:集成示例

现在将各个模块串联成一个可用的应用。以下是一个极简 React 组件的核心逻辑,你可以替换成任何前端框架。

import { useState, useEffect } from 'react';
import { auth, db } from './firebase/config';
import { 
  collection, addDoc, query, where, orderBy, onSnapshot, 
  doc, updateDoc, deleteDoc, serverTimestamp 
} from 'firebase/firestore';
import { onAuthStateChanged, signOut } from 'firebase/auth';

function App() {
  const [user, setUser] = useState(null);
  const [notes, setNotes] = useState([]);
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');

  useEffect(() => {
    const unsubscribeAuth = onAuthStateChanged(auth, (currentUser) => {
      setUser(currentUser);
      if (currentUser) {
        loadNotes(currentUser.uid);
      } else {
        setNotes([]);
      }
    });
    return () => unsubscribeAuth();
  }, []);

  const loadNotes = (uid) => {
    const q = query(
      collection(db, "notes"),
      where("userId", "==", uid),
      orderBy("updatedAt", "desc")
    );
    return onSnapshot(q, (snapshot) => {
      const list = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
      setNotes(list);
    });
  };

  const handleAddNote = async () => {
    await addDoc(collection(db, "notes"), {
      title,
      content,
      userId: user.uid,
      createdAt: serverTimestamp(),
      updatedAt: serverTimestamp()
    });
    setTitle('');
    setContent('');
  };

  const handleDelete = async (id) => {
    await deleteDoc(doc(db, "notes", id));
  };

  return (
    <div>
      {user ? (
        <>
          <button onClick={() => signOut(auth)}>退出</button>
          <input value={title} onChange={e => setTitle(e.target.value)} placeholder="标题" />
          <textarea value={content} onChange={e => setContent(e.target.value)} placeholder="内容" />
          <button onClick={handleAddNote}>添加笔记</button>
          {notes.map(note => (
            <div key={note.id}>
              <h3>{note.title}</h3>
              <p>{note.content}</p>
              <button onClick={() => handleDelete(note.id)}>删除</button>
            </div>
          ))}
        </>
      ) : (
        <LoginScreen />
      )}
    </div>
  );
}

所有后端逻辑——用户验证、数据存储、实时同步、统计更新自动运行在 Firebase 云端,前端只负责界面渲染和调用 SDK。


进阶方向与最佳实践

  1. 性能优化
    使用 Firestore 复合查询和索引。在控制台为复杂查询创建索引,避免全表扫描。

  2. 离线支持
    Firebase SDK 默认开启离线持久化。你在飞机上添加的笔记会在网络恢复后自动同步。

  3. 存储(Cloud Storage)
    可轻松扩展现有架构,将用户头像、文件上传到 Cloud Storage,并配合 Cloud Functions 生成缩略图。

  4. 监控与日志
    在 Firebase 控制台查看云函数的调用次数、错误率,使用 Cloud Logging 分析日志。

  5. 成本控制
    Firebase 免费额度非常充裕,适合原型和中小规模应用。但请务必设置预算警报,并优化查询以减少读取次数。

掌握认证、Firestore、云函数这三大支柱后,你事实上已经具备构建现代 Web/移动端全栈应用的完整能力。Firebase 消除了基础设施的复杂度,让你将 90% 的精力回归到产品逻辑本身,这才是高效开发的真正秘诀。