Flutter: Firebase 集成
Firebase 是 Flutter 的超级助手——Auth、数据库、存储、分析、推送,五合一开箱即用。
📋 前置知识:需要先掌握以下内容
- 第11课:网络请求与 REST API
- 第13课:本地存储
1. 你将学到
- Firebase 项目配置:FlutterFire CLI + firebase_options.dart 多平台配置
- Authentication:Email/Google/Apple Sign-In + 匿名登录 + 手机号验证
- Cloud Firestore:数据建模、实时监听 snapshots()、复合查询与安全规则
- Cloud Storage:商品图片上传/下载 + 缓存策略
- Analytics + Cloud Messaging:用户行为追踪 + 推送通知营销
2. 一个自建后端崩溃的真实故事
(1) 痛点:自建后端运维成本高
Bob 的 ShopApp 自建后端用 Node.js + PostgreSQL + S3,运维 3 人团队,月成本 20 thousand USD。一次数据库迁移导致 4 小时宕机,损失 50 thousand USD 订单。实时商品库存同步需要 WebSocket,自建方案复杂且不稳定。推送通知用第三方服务,经常延迟。
(2) Firebase 全家桶的解法
Firebase 提供了 Auth + Firestore + Storage + Analytics + FCM 一站式后端,无需运维服务器,实时数据自动同步。
DART
import 'package:cloud_firestore/cloud_firestore.dart';
// ⚙️ **安装依赖**:flutter pub add cloud_firestore
// 自定义类定义来源:
// - Product: 见第11课 json_serializable 模型(需添加 fromFirestore 工厂构造函数)
// Firestore real-time product updates
FirebaseFirestore.instance
.collection('products')
.where('stock', isGreaterThan: 0)
.snapshots()
.listen((snapshot) {
// UI auto-updates when stock changes
products = snapshot.docs.map((d) => Product.fromFirestore(d)).toList();
});
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
(3) 收益:零运维 + 实时同步 + 成本减半
Bob 迁移到 Firebase 后,后端运维团队缩减 2 人,月成本从 20 thousand USD 降到 8 thousand USD,实时数据延迟从秒级降到毫秒级。
3. Firebase 架构全景
graph TD
FB[Firebase] --> AUTH[Authentication]
FB --> FS[Cloud Firestore]
FB --> ST[Cloud Storage]
FB --> AN[Analytics]
FB --> CM[Cloud Messaging]
FS --> |snapshots| PL[ProductList Realtime]
AUTH --> |authStateChanges| LP[LoginPage]
CM --> |onMessage| NP[NotificationPopup]
AN --> |logEvent| DA[Dashboard Analytics]
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
(1) Firebase 服务矩阵
| 服务 | 用途 | 定价 |
|---|---|---|
| Authentication | 用户认证 | 免费额度大 |
| Cloud Firestore | NoSQL 实时数据库 | 免费额度:50K 读/天 |
| Cloud Storage | 文件存储 | 免费额度:5GB |
| Analytics | 用户行为分析 | 免费 |
| Cloud Messaging | 推送通知 | 免费 |
| Crashlytics | 崩溃上报 | 免费 |
4. Firebase 项目配置
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
:FlutterFire 初始化
BASH
# Install FlutterFire CLI
dart pub global activate flutterfire_cli
# Configure Firebase project
flutterfire configure
# Add dependencies
flutter pub add firebase_core firebase_auth cloud_firestore firebase_storage firebase_analytics firebase_messaging
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
DART
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
// ⚙️ **安装依赖**:flutter pub add firebase_core
// ⚙️ **项目配置**:dart pub global activate flutterfire_cli && flutterfire configure
// lib/main.dart
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(const ShopApp());
}
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
5. Authentication
(1) 登录方式对比
| 方式 | 复杂度 | 用户体验 | 适用场景 |
|---|---|---|---|
| Email/Password | 低 | 中 | 通用 |
| Google Sign-In | 中 | 高 | Android 首选 |
| Apple Sign-In | 中 | 高 | iOS 必需 |
| 匿名登录 | 低 | 高(无感) | 先体验后注册 |
| 手机号验证 | 高 | 中 | 验证身份 |
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
:AuthService 封装
DART
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
// ⚙️ **安装依赖**:flutter pub add firebase_auth google_sign_in
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
Stream<User?> get authStateChanges => _auth.authStateChanges();
Future<UserCredential> signInWithEmail(String email, String password) =>
_auth.signInWithEmailAndPassword(email: email, password: password);
Future<UserCredential> signUpWithEmail(String email, String password) =>
_auth.createUserWithEmailAndPassword(email: email, password: password);
Future<UserCredential> signInWithGoogle() async {
final googleUser = await GoogleSignIn().signIn();
final googleAuth = await googleUser?.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
return _auth.signInWithCredential(credential);
}
Future<UserCredential> signInAnonymously() => _auth.signInAnonymously();
Future<void> signOut() => _auth.signOut();
User? get currentUser => _auth.currentUser;
}
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
:Riverpod Auth Notifier + Firebase
DART
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
// ⚙️ **安装依赖**:flutter pub add firebase_auth flutter_riverpod riverpod_annotation
// ⚙️ **开发依赖**:flutter pub add --dev riverpod_generator build_runner
// 自定义类定义来源:
// - AuthService: 见本课第5节 AuthService 封装
@riverpod
class FirebaseAuth extends _$FirebaseAuth {
@override
AsyncValue<User?> build() {
final service = AuthService();
// Listen to auth state changes
service.authStateChanges.listen((user) {
state = AsyncData(user);
});
return AsyncData(service.currentUser);
}
Future<void> login(String email, String password) async {
state = const AsyncLoading();
state = await AsyncValue.guard(() => AuthService().signInWithEmail(email, password));
}
Future<void> loginWithGoogle() async {
state = const AsyncLoading();
state = await AsyncValue.guard(() => AuthService().signInWithGoogle());
}
Future<void> logout() async {
await AuthService().signOut();
}
}
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
6. Cloud Firestore
(1) 数据建模
TEXT
📖 仅展示
firestore/
├── products/{productId}
│ ├── name: "Pro Laptop"
│ ├── price: 1299.99
│ ├── stock: 150
│ ├── category: "Electronics"
│ └── imageUrl: "gs://shopapp.appspot.com/products/laptop.jpg"
├── users/{userId}
│ ├── name: "Bob"
│ ├── email: "alice@shopapp.com"
│ ├── addresses: [{...}]
│ └── preferences: {theme: "dark", currency: "USD"}
├── orders/{orderId}
│ ├── userId: "alice_123"
│ ├── items: [{productId, quantity, price}]
│ ├── total: 99.99
│ ├── status: "shipped"
│ └── createdAt: Timestamp
└── reviews/{reviewId}
├── productId: "laptop_001"
├── userId: "bob_456"
├── rating: 4.5
└── comment: "Great product!"
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
:Firestore CRUD
DART
import 'package:cloud_firestore/cloud_firestore.dart';
// ⚙️ **安装依赖**:flutter pub add cloud_firestore
// 自定义类定义来源:
// - Product: 见第11课 json_serializable 模型(需添加 fromFirestore 工厂构造函数)
class ProductFirestore {
final _db = FirebaseFirestore.instance;
Future<List<Product>> getProducts({String? category, int limit = 20}) async {
Query query = _db.collection('products').orderBy('rating', descending: true).limit(limit);
if (category != null) query = query.where('category', isEqualTo: category);
final snapshot = await query.get();
return snapshot.docs.map((d) => Product.fromFirestore(d)).toList();
}
Future<Product> getProduct(String id) async {
final doc = await _db.collection('products').doc(id).get();
return Product.fromFirestore(doc);
}
// Real-time listener
Stream<List<Product>> watchProducts({String? category}) {
Query query = _db.collection('products').where('stock', isGreaterThan: 0);
if (category != null) query = query.where('category', isEqualTo: category);
return query.snapshots().map((s) => s.docs.map((d) => Product.fromFirestore(d)).toList());
}
Future<void> updateStock(String productId, int newStock) =>
_db.collection('products').doc(productId).update({'stock': newStock});
}
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
:Firestore 安全规则
JAVASCRIPT
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Products: anyone can read, only admins can write
match /products/{productId} {
allow read: if true;
allow write: if isAdmin();
}
// Orders: users can read/write own orders
match /orders/{orderId} {
allow read, write: if request.auth != null && request.auth.uid == resource.data.userId;
allow create: if request.auth != null;
}
// Reviews: anyone can read, authenticated users can create
match /reviews/{reviewId} {
allow read: if true;
allow create: if request.auth != null;
}
}
}
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
7. Cloud Storage
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
:商品图片上传与下载
DART
import 'package:firebase_storage/firebase_storage.dart';
import 'dart:io';
// ⚙️ **安装依赖**:flutter pub add firebase_storage
class StorageService {
final _storage = FirebaseStorage.instance;
Future<String> uploadProductImage(String filePath, String productId) async {
final ref = _storage.ref().child('products/$productId/${DateTime.now().millisecondsSinceEpoch}.jpg');
final uploadTask = ref.putFile(File(filePath));
final snapshot = await uploadTask;
return await snapshot.ref.getDownloadURL();
}
Future<String> getDownloadUrl(String path) =>
_storage.ref().child(path).getDownloadURL();
// Upload with progress
Stream<double> uploadWithProgress(String filePath, String productId) {
final ref = _storage.ref().child('products/$productId/main.jpg');
return ref.putFile(File(filePath)).snapshotEvents.map((s) {
return s.bytesTransferred / s.totalBytes;
});
}
}
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
8. Analytics + Cloud Messaging
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
:Analytics 埋点
DART
import 'package:firebase_analytics/firebase_analytics.dart';
// ⚙️ **安装依赖**:flutter pub add firebase_analytics
// 自定义类定义来源:
// - Product: 见第11课 json_serializable 模型
// - Order: 见第14课 Order 模型
class ShopAnalytics {
static final _analytics = FirebaseAnalytics.instance;
static Future<void> logViewProduct(Product product) =>
_analytics.logEvent(name: 'view_product', parameters: {
'product_id': product.id,
'product_name': product.name,
'price': product.price,
'category': product.category,
});
static Future<void> logAddToCart(Product product, int quantity) =>
_analytics.logEvent(name: 'add_to_cart', parameters: {
'product_id': product.id,
'quantity': quantity,
'price': product.price,
'currency': 'USD',
});
static Future<void> logPurchase(Order order) =>
_analytics.logEvent(name: 'purchase', parameters: {
'order_id': order.id,
'value': order.total,
'currency': 'USD',
'item_count': order.items.length,
});
static Future<void> setUserProperty(String name, String value) =>
_analytics.setUserProperty(name: name, value: value);
}
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
▶ 示例
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
:FCM 推送通知
DART
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
// ⚙️ **安装依赖**:flutter pub add firebase_messaging
class NotificationService {
static final _messaging = FirebaseMessaging.instance;
static Future<void> init() async {
// Request permission
await _messaging.requestPermission();
// Get FCM token
final token = await _messaging.getToken();
debugPrint('FCM Token: $token');
// Foreground messages
FirebaseMessaging.onMessage.listen((message) {
debugPrint('Foreground message: ${message.notification?.title}');
});
// Background messages
FirebaseMessaging.onMessageOpenedApp.listen((message) {
// Handle notification tap
final productId = message.data['product_id'];
if (productId != null) {
// Navigate to product detail
}
});
}
}
TEXT
📖 仅展示
> **输出:** 在本地 Flutter SDK(Flutter 3.x / Dart 3.x)运行。Piston 服务器未安装 Flutter,请在本机 `flutter run` 实操对照。实际 UI/状态会因平台略有差异。
❓ 常见问题
Q Firebase 免费额度够用吗?
A Firestore 免费 50K 读/20K 写/天,小规模应用足够。百万级 DAU 需要付费方案。
Q Firestore 和 Realtime Database 怎么选?
A 新项目用 Firestore(更强大的查询、更好的数据模型)。Realtime Database 仅适合需要极低延迟的实时场景。
Q Firebase Auth 的 Token 怎么和后端 API 集成?
A 用
await user.getIdToken() 获取 JWT,传给后端验证。后端用 Firebase Admin SDK 验证 Token。Q Firestore 查询有索引限制吗?
A 复合查询需要创建复合索引。首次执行时 Firestore 会报错并给出创建索引的链接。
Q FCM 推送在中国大陆能用吗?
A 不能。中国大陆需要集成厂商推送(华为/小米/OPPO/VIVO),或使用极光推送等第三方服务。
Q Firestore 安全规则怎么调试?
A Firebase Console 的 Rules Playground 可以模拟读写请求测试规则。生产环境务必设置严格规则。
📖 小节
- Firebase 一站式后端:Auth + Firestore + Storage + Analytics + FCM
- FlutterFire CLI 自动生成多平台配置
- Auth 支持多种登录方式,authStateChanges 实时监听登录状态
- Firestore snapshots() 实现实时数据同步,安全规则保护数据
- Analytics 埋点追踪用户行为,FCM 实现推送通知
📝 作业
- 基础题(难度⭐):配置 Firebase 项目,实现 Email/Password 注册和登录,监听 authStateChanges 显示用户状态。
- 进阶题(难度⭐⭐):实现 Firestore 商品 CRUD + 实时监听,商品库存变化时 UI 自动更新。
- 挑战题(难度⭐⭐⭐):实现完整 Firebase 集成:Google 登录 + Firestore 实时商品 + Storage 图片上传(带进度)+ Analytics 事件追踪 + FCM 推送通知。