146 lines
4.6 KiB
Dart
146 lines
4.6 KiB
Dart
import 'dart:async';
|
|
import 'dart:ui';
|
|
|
|
import 'package:firebase_analytics/firebase_analytics.dart';
|
|
import 'package:firebase_analytics/observer.dart';
|
|
import 'package:firebase_core/firebase_core.dart';
|
|
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import 'package:hive_flutter/hive_flutter.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
import 'adstools/firebase_optiongs.dart';
|
|
import 'services/hydration_service.dart';
|
|
import 'widgets/main_navigation_frame.dart';
|
|
|
|
bool isFirebaseInitialized = false;
|
|
|
|
void main() async {
|
|
runZonedGuarded<Future<void>>(() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
try {
|
|
await Firebase.initializeApp(
|
|
options: DefaultFirebaseOptions.currentPlatform,
|
|
).timeout(const Duration(seconds: 15)); // 设置15秒超时
|
|
print("✅ Firebase 初始化成功。");
|
|
isFirebaseInitialized = true; // 成功后设置标志
|
|
} on TimeoutException {
|
|
print("⚠️ Firebase 初始化超时 (超过15秒),应用将继续运行但相关功能将不可用。");
|
|
} catch (error, stack) {
|
|
print("!!!!!!!!!! Firebase 初始化失败 !!!!!!!!!!: $error");
|
|
FirebaseCrashlytics.instance.recordError(error, stack, fatal: false);
|
|
}
|
|
|
|
// Firebase 成功初始化后,配置依赖它的服务
|
|
if (isFirebaseInitialized) {
|
|
//设置全局错误处理器
|
|
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
|
|
PlatformDispatcher.instance.onError = (error, stack) {
|
|
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
|
|
return true;
|
|
};
|
|
// 使用我们的安全服务来记录 App Open
|
|
AnalyticsService.instance.logAppOpen();
|
|
}
|
|
|
|
await Hive.initFlutter();
|
|
await Hive.openBox('hydrationData');
|
|
await Hive.openBox('userSettings');
|
|
|
|
final analyticsObserver = SafeFirebaseAnalyticsObserver();
|
|
runApp(
|
|
MultiProvider(
|
|
providers: [ChangeNotifierProvider(create: (_) => HydrationService())],
|
|
child: BioFluxApp(analyticsObserver: analyticsObserver),
|
|
),
|
|
);
|
|
}, (e, s) {});
|
|
}
|
|
|
|
class BioFluxApp extends StatelessWidget {
|
|
final NavigatorObserver analyticsObserver;
|
|
|
|
const BioFluxApp({super.key, required this.analyticsObserver});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
title: 'BioFlux',
|
|
navigatorObservers: [analyticsObserver],
|
|
debugShowCheckedModeBanner: false,
|
|
theme: ThemeData(
|
|
useMaterial3: true,
|
|
scaffoldBackgroundColor: const Color(0xFFF0F8FF),
|
|
colorScheme: ColorScheme.fromSeed(
|
|
seedColor: const Color(0xFF00BFFF),
|
|
background: const Color(0xFFF0F8FF),
|
|
),
|
|
textTheme: GoogleFonts.latoTextTheme(Theme.of(context).textTheme)
|
|
.copyWith(
|
|
displayLarge: GoogleFonts.montserrat(),
|
|
displayMedium: GoogleFonts.montserrat(),
|
|
titleLarge: GoogleFonts.montserrat(fontWeight: FontWeight.w600),
|
|
titleMedium: GoogleFonts.montserrat(fontWeight: FontWeight.w600),
|
|
bodyLarge: GoogleFonts.lato(),
|
|
bodyMedium: GoogleFonts.lato(),
|
|
),
|
|
),
|
|
home: const MainNavigationFrame(),
|
|
);
|
|
}
|
|
}
|
|
|
|
class AnalyticsService {
|
|
// 单例模式
|
|
AnalyticsService._();
|
|
|
|
static final instance = AnalyticsService._();
|
|
|
|
final _analytics = FirebaseAnalytics.instance;
|
|
|
|
/// 安全地记录一个 App Open 事件。
|
|
void logAppOpen() {
|
|
if (isFirebaseInitialized) {
|
|
_analytics.logAppOpen();
|
|
} else {
|
|
print("[AnalyticsService] Skipped logAppOpen: Firebase not initialized.");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 一个安全的 FirebaseAnalyticsObserver 包装器。它只在 Firebase 初始化成功时才转发导航事件。
|
|
class SafeFirebaseAnalyticsObserver extends NavigatorObserver {
|
|
late final FirebaseAnalyticsObserver _observer;
|
|
|
|
SafeFirebaseAnalyticsObserver() {
|
|
if (isFirebaseInitialized) {
|
|
_observer = FirebaseAnalyticsObserver(
|
|
analytics: AnalyticsService.instance._analytics,
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
|
|
if (isFirebaseInitialized) {
|
|
_observer.didPush(route, previousRoute);
|
|
}
|
|
}
|
|
|
|
@override
|
|
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
|
|
if (isFirebaseInitialized) {
|
|
_observer.didPop(route, previousRoute);
|
|
}
|
|
}
|
|
|
|
@override
|
|
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
|
|
if (isFirebaseInitialized) {
|
|
_observer.didReplace(newRoute: newRoute, oldRoute: oldRoute);
|
|
}
|
|
}
|
|
}
|