CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Flutter 开发入门/课时/Firebase 集成
RawBlame
课时目录12 节

Flutter 开发入门

  1. 01Flutter 环境
  2. 02Dart 语言
  3. 03Widget 体系
  4. 04架构原则
  5. 05状态管理
  6. 06动画
  7. 07网络与本地存储
  8. 08Firebase 集成
  9. 09测试
  10. 10CI/CD 与发布
  11. 11分析与监控
  12. 12综合练习

Firebase 集成

Auth、Firestore 与推送。

30 分钟

Firebase 集成

这一课你将能做到

  1. 用 FlutterFire CLI 把 Firebase 项目接入 Flutter(Android + iOS 双端)
  2. 用 Firebase Auth 实现邮箱注册/登录、Google 登录,并管理登录态
  3. 用 Cloud Firestore 做实时数据读写,并接入 Firebase Cloud Messaging 接收推送

为什么要学

Firebase 给 Flutter 提供「开箱即用的后端」:认证、数据库、推送、崩溃分析、AB 测试。不会 Firebase,做个人项目就只能手撸后端。即使是公司项目,理解 Firebase 也有助于理解 BaaS 模式。

人话:Firebase 就像「云端全家桶」,认证、数据库、推送、分析一锅端,让你专注写 UI 和业务。

先建立图像

Flutter App
  ├── FirebaseAuth            ← 登录 / 注册 / 登出
  ├── Cloud Firestore         ← NoSQL 实时数据库
  ├── Firebase Cloud Messaging← 推送通知
  ├── Firebase Crashlytics    ← 崩溃上报
  └── Firebase Analytics      ← 埋点统计

跟着做

步骤 1:创建 Firebase 项目并初始化 FlutterFire

  1. 打开 <https://console.firebase.google.com>,创建一个项目(比如叫 flutter-demo)。
  2. 安装 FlutterFire CLI:
dart pub global activate flutterfire_cli
  1. 在 Flutter 项目根目录运行:
flutterfire configure

按提示选 Firebase 项目、勾选 Android 和 iOS。CLI 会自动:

  • 生成 firebase_options.dart(包含各平台的 API Key)
  • 在 Android 项目里下载 google-services.json
  • 在 iOS 项目里下载 GoogleService-Info.plist
  1. pubspec.yaml 加依赖:
dependencies:
  firebase_core: ^2.24.0
  firebase_auth: ^4.16.0
  cloud_firestore: ^4.15.0
  firebase_messaging: ^14.7.0
  firebase_crashlytics: ^3.4.0

步骤 2:初始化 Firebase

import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const MyApp());
}

关键:WidgetsFlutterBinding.ensureInitialized() 必须最先调用,否则原生插件可能没准备好。

步骤 3:邮箱注册 / 登录

import 'package:firebase_auth/firebase_auth.dart';

class AuthService {
  final _auth = FirebaseAuth.instance;

  Stream<User?> get authState => _auth.authStateChanges();

  Future<UserCredential> signUp(String email, String password) {
    return _auth.createUserWithEmailAndPassword(email: email, password: password);
  }

  Future<UserCredential> signIn(String email, String password) {
    return _auth.signInWithEmailAndPassword(email: email, password: password);
  }

  Future<void> signOut() => _auth.signOut();

  User? get currentUser => _auth.currentUser;
}

监听登录态切换页面:

class AuthGate extends StatelessWidget {
  const AuthGate({super.key});
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<User?>(
      stream: AuthService().authState,
      builder: (ctx, snap) {
        if (snap.connectionState == ConnectionState.waiting) {
          return const Scaffold(body: Center(child: CircularProgressIndicator()));
        }
        if (snap.hasData) return const HomePage();
        return const LoginPage();
      },
    );
  }
}

步骤 4:Google 登录

dependencies:
  google_sign_in: ^6.2.0
import 'package:google_sign_in/google_sign_in.dart';

Future<UserCredential> signInWithGoogle() async {
  final googleUser = await GoogleSignIn().signIn();
  if (googleUser == null) throw Exception('用户取消');

  final googleAuth = await googleUser.authentication;
  final credential = GoogleAuthProvider.credential(
    accessToken: googleAuth.accessToken,
    idToken: googleAuth.idToken,
  );
  return FirebaseAuth.instance.signInWithCredential(credential);
}

Android 需要在 Firebase Console 下载 SHA-1 并填到项目设置;iOS 需要在 Info.plist 里加 REVERSED_CLIENT_ID。

步骤 5:Cloud Firestore 读写

import 'package:cloud_firestore/cloud_firestore.dart';

class TodoService {
  final _db = FirebaseFirestore.instance;
  final _col = 'todos';

  Stream<List<Todo>> watchTodos(String uid) {
    return _db.collection(_col)
        .where('uid', isEqualTo: uid)
        .orderBy('createdAt', descending: true)
        .snapshots()
        .map((snap) => snap.docs.map((d) => Todo.fromJson(d.data())).toList());
  }

  Future<void> addTodo(String uid, String title) {
    return _db.collection(_col).add({
      'uid': uid,
      'title': title,
      'done': false,
      'createdAt': FieldValue.serverTimestamp(),
    });
  }

  Future<void> toggleDone(String docId, bool done) {
    return _db.collection(_col).doc(docId).update({'done': done});
  }

  Future<void> deleteTodo(String docId) {
    return _db.collection(_col).doc(docId).delete();
  }
}

核心概念:

  • Collection:表,如 todos
  • Document:行,有自动生成的 ID
  • Query:条件查询,where + orderBy 需要建索引
  • snapshots():返回 Stream,数据变化时自动推送,实时同步

步骤 6:Firebase Cloud Messaging 推送

import 'package:firebase_messaging/firebase_messaging.dart';

Future<void> setupFCM() async {
  final messaging = FirebaseMessaging.instance;

  // 请求权限
  final settings = await messaging.requestPermission();
  if (settings.authorizationStatus != AuthorizationStatus.authorized) return;

  // 获取 token(用于后端定向推送)
  final token = await messaging.getToken();
  debugPrint('FCM token: $token');

  // 前台消息
  FirebaseMessaging.onMessage.listen((msg) {
    debugPrint('前台收到: ${msg.notification?.title}');
  });

  // 点击通知打开 App
  FirebaseMessaging.onMessageOpenedApp.listen((msg) {
    debugPrint('用户点击了通知: ${msg.data}');
  });
}

Android 需在 AndroidManifest.xml 声明 INTERNET 权限;iOS 需开启 Push Notifications capability,并上传 APNs key 到 Firebase Console。

步骤 7:Crashlytics 崩溃上报

import 'package:firebase_crashlytics/firebase_crashlytics.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

  // 捕获 Flutter 框架异常
  FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;

  // 捕获异步异常
  PlatformDispatcher.instance.onError = (error, stack) {
    FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
    return true;
  };

  runApp(const MyApp());
}

讲清楚要点

  1. FlutterFire CLI 是官方推荐方式:自动处理 Android/iOS 双端配置,避免手动下载 json/plist 放错位置。
  2. Firebase Auth 的 User 对象:uid 是全局唯一 ID,所有业务数据都应该以 uid 作为外键。
  3. Firestore 是 NoSQL:没有 JOIN,靠「冗余存储」和「聚合查询」设计 schema;实时同步靠 snapshots() Stream。
  4. FCM 三种消息:通知消息(系统托盘展示)、数据消息(App 自己处理)、前台消息(onMessage 回调)。
  5. Crashlytics 必须在 runApp 前初始化:否则启动崩溃抓不到。

你可能会懵的地方

  • Firebase 免费吗? Spark 计划免费:Auth 无限、Firestore 1GB 存储/5 万读/2 万写、FCM 无限。个人项目足够;商业项目看用量。

  • Firestore 和 Realtime Database 选哪个? Firestore 是新一代,查询更强、扩展更好;Realtime Database 延迟更低但功能少。新项目一律 Firestore。

  • 为什么 Google 登录在 Android 上报错? 缺少 SHA-1 指纹。运行 cd android && ./gradlew signingReport,把 debug SHA-1 填到 Firebase Console → Project Settings → Android App。

  • FCM token 会变吗? 会。App 卸载重装、清除数据、系统刷新 token 时都会变。App 启动时应该重新获取并上报到后端。

  • Firestore 的 where + orderBy 报错? 需要复合索引。错误信息里会带一个链接,点进去一键创建索引。

错法对照

错法问题正解
main() 里不 ensureInitializedFirebase 初始化失败第一行就调 WidgetsFlutterBinding.ensureInitialized()
把 google-services.json 提交到公开仓库API Key 泄露加 .gitignore,或确保仓库私有
Firestore 查询用 == 判断字符串大小写敏感,查不到存 lowercase 字段,或全量拉下来本地过滤
在 build() 里直接调 FirebaseAuth.instance.currentUser登录态变化时不会自动 rebuild用 StreamBuilder 监听 authStateChanges()
FCM 前台消息不弹通知前台时系统不自动弹监听 onMessage,用 flutter_local_notifications 手动弹

卡点急救

  1. flutterfire configure 报错:先 firebase login;Windows 上确保 dart pub global 的 bin 目录在 PATH。
  2. iOS 编译报 GoogleService-Info.plist 找不到:确认文件在 ios/Runner/ 目录下,且已加入 Xcode 项目。
  3. Auth 报 email-already-in-use:捕获 FirebaseAuthException,按 code 字段给用户提示。
  4. FCM 收不到推送:Android 检查 google-services.json 是否最新;iOS 检查 APNs key 是否上传、设备是否真机(模拟器收不到 APNs)。
  5. Firestore 写入成功但 UI 不更新:确认用的是 snapshots() 而不是 get();get() 是一次性读取,不监听变化。

面试常问

  • Firebase Auth 的 token 机制? 登录成功后返回 idToken(JWT),有效期 1 小时;SDK 自动用 refreshToken 续期。后端可以用 Admin SDK 验证 idToken 的合法性。

  • Firestore 和 SQL 的区别? Firestore 是 NoSQL 文档数据库,schema-less,靠「反规范化」设计;没有 JOIN,查询条件有限;优势是实时同步、自动扩展、离线缓存。

  • FCM 的消息类型? 通知消息(Notification Message):系统托盘展示,App 在后台时点击打开;数据消息(Data Message):完全由 App 处理,可自定义行为。

  • Firebase 的离线机制? Firestore 默认开启离线持久化:读过的数据缓存到本地,离线时可读;写操作在离线时排队,恢复网络后自动同步。

自测三问

  1. flutterfire configure 做了哪三件事?
  2. 写一段代码:监听 Firebase Auth 登录态,已登录显示首页,未登录显示登录页。
  3. Firestore 的 snapshots() 和 get() 有什么区别?

小结一句话

Firebase = 认证 + Firestore + FCM + Crashlytics 的组合拳;FlutterFire CLI 一键接入,Auth 管登录态,Firestore 管实时数据,FCM 管推送,Crashlytics 管崩溃。

延伸

  • FlutterFire 官方文档:<https://firebase.google.com/docs/flutter/setup>
  • Firebase Console:<https://console.firebase.google.com>
  • 下一课:测试,给 Flutter 代码加上质量保险。
加载本节练习…
← 上一课网络与本地存储下一课 →测试