GitHub_Trending/sam/samples Firebase:Google云服务平台完整集成
概述
Firebase是Google提供的全方位移动和Web应用开发平台,为开发者提供后端服务、实时数据库、认证、分析、推送通知等强大功能。在GitHub_Trending/sam/samples项目中,我们通过game_template示例展示了如何在Flutter应用中完整集成Firebase服务。
Firebase核心服务架构
环境配置与依赖管理
1. 添加Firebase依赖
在pubspec.yaml中添加必要的Firebase包:
dependencies:
flutter:
sdk: flutter
firebase_core: ^4.0.0 # Firebase核心库
firebase_crashlytics: ^5.0.0 # 崩溃报告
firebase_auth: ^6.0.0 # 用户认证
cloud_firestore: ^6.0.0 # 实时数据库
firebase_storage: ^14.0.0 # 文件存储
firebase_messaging: ^15.0.0 # 推送通知
google_sign_in: ^7.0.0 # Google登录
2. 平台特定配置
Android配置 (android/app/src/main/AndroidManifest.xml)
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="Your App"
android:name="${applicationName}">
<!-- Firebase配置 -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
</application>
</manifest>
iOS配置 (ios/Runner/Info.plist)
<dict>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
</dict>
Firebase初始化与配置
1. Firebase选项配置
创建lib/firebase_options.dart文件:
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
return FirebaseOptions(
apiKey: 'your-api-key',
appId: 'your-app-id',
messagingSenderId: 'your-sender-id',
projectId: 'your-project-id',
authDomain: 'your-project.firebaseapp.com',
storageBucket: 'your-project.appspot.com',
measurementId: 'G-XXXXXXXXXX',
);
}
}
2. 应用初始化
在lib/main.dart中进行Firebase初始化:
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化Firebase
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// 配置Crashlytics
FlutterError.onError = (errorDetails) {
FirebaseCrashlytics.instance.recordFlutterError(errorDetails);
};
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
runApp(MyApp());
}
Firebase Crashlytics集成
1. 错误报告配置
class CrashlyticsService {
static final CrashlyticsService _instance = CrashlyticsService._internal();
factory CrashlyticsService() => _instance;
CrashlyticsService._internal();
// 记录自定义错误
Future<void> recordError(
dynamic error,
StackTrace stackTrace, {
String? reason,
bool fatal = false,
}) async {
await FirebaseCrashlytics.instance.recordError(
error,
stackTrace,
reason: reason,
fatal: fatal,
);
}
// 设置用户标识
Future<void> setUserId(String userId) async {
await FirebaseCrashlytics.instance.setUserIdentifier(userId);
}
// 添加自定义日志
Future<void> log(String message) async {
await FirebaseCrashlytics.instance.log(message);
}
// 设置自定义键值对
Future<void> setCustomKey(String key, dynamic value) async {
await FirebaseCrashlytics.instance.setCustomKey(key, value);
}
}
2. 错误处理最佳实践
void performRiskyOperation() async {
try {
// 可能抛出异常的操作
await someNetworkCall();
} catch (error, stackTrace) {
// 记录非致命错误
await CrashlyticsService().recordError(
error,
stackTrace,
reason: 'Network call failed',
fatal: false,
);
// 添加上下文信息
await CrashlyticsService().setCustomKey('operation_type', 'network');
await CrashlyticsService().setCustomKey('retry_count', 3);
// 重新抛出或处理错误
rethrow;
}
}
Firebase Authentication集成
1. 用户认证服务
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// 邮箱密码注册
Future<User?> signUpWithEmail(String email, String password) async {
try {
UserCredential result = await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
return result.user;
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
// 邮箱密码登录
Future<User?> signInWithEmail(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(
email: email,
password: password,
);
return result.user;
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
// Google登录
Future<User?> signInWithGoogle() async {
try {
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
final GoogleSignInAuthentication? googleAuth =
await googleUser?.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
UserCredential result = await _auth.signInWithCredential(credential);
return result.user;
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
// 登出
Future<void> signOut() async {
await _auth.signOut();
await GoogleSignIn().signOut();
}
// 监听认证状态变化
Stream<User?> get authStateChanges => _auth.authStateChanges();
}
2. 认证状态管理
class AuthProvider with ChangeNotifier {
User? _user;
final AuthService _authService = AuthService();
AuthProvider() {
_authService.authStateChanges.listen((user) {
_user = user;
notifyListeners();
});
}
User? get user => _user;
bool get isAuthenticated => _user != null;
Future<void> signInWithEmail(String email, String password) async {
try {
await _authService.signInWithEmail(email, password);
} catch (e) {
rethrow;
}
}
Future<void> signOut() async {
await _authService.signOut();
}
}
Cloud Firestore集成
1. 数据库服务层
class FirestoreService {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
// 添加文档
Future<void> addDocument(String collection, Map<String, dynamic> data) async {
try {
await _firestore.collection(collection).add(data);
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
// 更新文档
Future<void> updateDocument(
String collection,
String docId,
Map<String, dynamic> updates,
) async {
try {
await _firestore.collection(collection).doc(docId).update(updates);
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
// 查询文档
Stream<List<Map<String, dynamic>>> getDocuments(
String collection, {
Query Function(Query)? queryBuilder,
int? limit,
}) {
Query query = _firestore.collection(collection);
if (queryBuilder != null) {
query = queryBuilder(query);
}
if (limit != null) {
query = query.limit(limit);
}
return query.snapshots().map((snapshot) {
return snapshot.docs.map((doc) {
return {
'id': doc.id,
...doc.data() as Map<String, dynamic>,
};
}).toList();
});
}
// 实时监听单个文档
Stream<Map<String, dynamic>?> getDocument(
String collection,
String docId,
) {
return _firestore
.collection(collection)
.doc(docId)
.snapshots()
.map((snapshot) {
if (snapshot.exists) {
return {
'id': snapshot.id,
...snapshot.data() as Map<String, dynamic>,
};
}
return null;
});
}
}
2. 数据模型示例
class UserProfile {
final String id;
final String email;
final String displayName;
final DateTime createdAt;
final DateTime? lastLogin;
UserProfile({
required this.id,
required this.email,
required this.displayName,
required this.createdAt,
this.lastLogin,
});
// 从Firestore文档转换
factory UserProfile.fromFirestore(DocumentSnapshot doc) {
final data = doc.data() as Map<String, dynamic>;
return UserProfile(
id: doc.id,
email: data['email'] ?? '',
displayName: data['displayName'] ?? '',
createdAt: (data['createdAt'] as Timestamp).toDate(),
lastLogin: data['lastLogin'] != null
? (data['lastLogin'] as Timestamp).toDate()
: null,
);
}
// 转换为Firestore文档
Map<String, dynamic> toFirestore() {
return {
'email': email,
'displayName': displayName,
'createdAt': Timestamp.fromDate(createdAt),
'lastLogin': lastLogin != null ? Timestamp.fromDate(lastLogin!) : null,
};
}
}
Firebase Storage集成
1. 文件存储服务
class StorageService {
final FirebaseStorage _storage = FirebaseStorage.instance;
// 上传文件
Future<String> uploadFile(
String path,
Uint8List fileBytes, {
String? userId,
}) async {
try {
final ref = _storage.ref().child(
userId != null ? 'users/$userId/$path' : path,
);
final uploadTask = ref.putData(fileBytes);
final snapshot = await uploadTask;
return await snapshot.ref.getDownloadURL();
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
// 下载文件
Future<Uint8List> downloadFile(String path) async {
try {
final ref = _storage.ref().child(path);
return await ref.getData() ?? Uint8List(0);
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
// 获取文件下载URL
Future<String> getDownloadUrl(String path) async {
try {
final ref = _storage.ref().child(path);
return await ref.getDownloadURL();
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
// 删除文件
Future<void> deleteFile(String path) async {
try {
final ref = _storage.ref().child(path);
await ref.delete();
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
}
安全规则配置
1. Firestore安全规则
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// 用户资料:仅用户自己可读写
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// 公开数据:所有人可读,仅认证用户可写
match /public/{document} {
allow read: if true;
allow write: if request.auth != null;
}
// 管理员数据:仅管理员可访问
match /admin/{document} {
allow read, write: if request.auth != null
&& get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true;
}
}
}
2. Storage安全规则
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// 用户文件:仅用户自己可访问
match /users/{userId}/{allPaths=**} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// 公开文件:所有人可读
match /public/{allPaths=**} {
allow read: if true;
allow write: if request.auth != null;
}
}
}
性能优化与最佳实践
1. 查询优化策略
class OptimizedQueries {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
// 使用索引优化查询
Stream<List<UserProfile>> getActiveUsers(int limit) {
return _firestore
.collection('users')
.where('isActive', isEqualTo: true)
.orderBy('lastActivity', descending: true)
.limit(limit)
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => UserProfile.fromFirestore(doc))
.toList());
}
// 批量操作减少网络请求
Future<void> batchUpdateUsers(List<String> userIds, Map<String, dynamic> updates) async {
final batch = _firestore.batch();
for (final userId in userIds) {
final docRef = _firestore.collection('users').doc(userId);
batch.update(docRef, updates);
}
try {
await batch.commit();
} catch (e) {
await CrashlyticsService().recordError(e, StackTrace.current);
rethrow;
}
}
// 使用游标分页
Future<QuerySnapshot> getUsersPage({
required int limit,
DocumentSnapshot? startAfter,
}) async {
Query query = _firestore
.collection('users')
.orderBy('createdAt')
.limit(limit);
if (startAfter != null) {
query = query.startAfterDocument(startAfter);
}
return await query.get();
}
}
2. 错误处理与重试机制
class ResilientFirebaseService {
final int maxRetries = 3;
final Duration initialDelay = Duration(seconds: 1);
Future<T> executeWithRetry<T>(
Future<T> Function() operation, {
String? operationName,
}) async {
int attempt = 0;
Duration delay = initialDelay;
while (true) {
try {
return await operation();
} catch (e) {
attempt++;
if (attempt > maxRetries) {
await CrashlyticsService().recordError(
e,
StackTrace.current,
reason: 'Max retries exceeded for $operationName',
);
rethrow;
}
// 指数退避策略
await Future.delayed(delay);
delay *= 2;
}
}
}
}
测试策略
1. 单元测试配置
void main() {
group('Firebase Services', () {
late MockFirebaseAuth mockAuth;
late MockFirebaseFirestore mockFirestore;
late AuthService authService;
setUp(() {
mockAuth = MockFirebaseAuth();
mockFirestore = MockFirebaseFirestore();
authService = AuthService();
});
test('signInWithEmail should return user on success', () async {
// 配置mock
when(mockAuth.signInWithEmailAndPassword(
email: 'test@example.com',
password: 'password123',
)).thenAnswer((_) async => MockUserCredential());
// 执行测试
final result = await authService.signInWithEmail(
'test@example.com',
'password123',
);
// 验证结果
expect(result, isNotNull);
});
});
}
2. 集成测试
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('Firebase integration test', (WidgetTester tester) async {
// 初始化Firebase
await Firebase.initializeApp();
// 构建应用
await tester.pumpWidget(MyApp());
// 执行认证操作
final authButton = find.byKey(Key('sign_in_button'));
await tester.tap(authButton);
await tester.pumpAndSettle();
// 验证认证状态
expect(find.text('Welcome'), findsOneWidget);
});
}
部署与监控
1. 性能监控配置
class PerformanceMonitor {
final FirebasePerformance _performance = FirebasePerformance.instance;
Future<void> trackOperation(
String operationName,
Future<void> Function() operation,
) async {
final trace = _performance.newTrace(operationName);
await trace.start();
try {
await operation();
await trace.stop();
} catch (e) {
await trace.putAttribute('error', e.toString());
await trace.stop();
rethrow;
}
}
// 自定义指标跟踪
Future<void> trackCustomMetric(
String metricName,
int value,
) async {
final trace = _performance.newTrace('custom_metrics');
await trace.start();
await trace.incrementMetric(metricName, value);
await trace.stop();
}
}
2. 日志与调试
class FirebaseLogger {
static const _enableDebugLogs = bool.fromEnvironment('DEBUG_LOGS');
static void debug(String message) {
if (_enableDebugLogs) {
CrashlyticsService().log('DEBUG: $message');
}
}
static void info(String message) {
CrashlyticsService().log('INFO: $message');
}
static void warning(String message) {
CrashlyticsService().log('WARNING: $message');
}
static void error(String message, [dynamic error, StackTrace? stackTrace]) {
CrashlyticsService().log('ERROR: $message');
if (error != null && stackTrace != null) {
CrashlyticsService().recordError(error, stackTrace);
}
}
}
总结
通过GitHub_Trending/sam/samples项目的game_template示例,我们展示了如何在Flutter应用中完整集成Firebase服务。从核心初始化到各个服务的具体实现,本文提供了详细的代码示例和最佳实践。
Firebase为移动应用开发提供了强大的后端支持,包括用户认证、实时数据库、文件存储、错误报告等功能。通过合理的架构设计和错误处理机制,可以构建出稳定、高效的移动应用。
关键要点:
- 使用分层架构分离业务逻辑和Firebase服务
- 实现完善的错误处理和重试机制
- 配置适当的安全规则保护用户数据
- 使用性能监控和日志记录优化应用性能
- 编写全面的测试用例确保代码质量
通过遵循这些最佳实践,开发者可以充分利用Firebase的强大功能,构建出高质量的Flutter应用。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



