Files
BlockSeasons/lib/main.dart
T
airkjw 41b0180b44 feat(analytics): wire Firebase Analytics into app startup
flutterfire configure registered the iOS/Android apps under project
block-seasons and generated firebase_options.dart + native config. main()
now initializes Firebase and routes analytics through FirebaseAnalyticsBackend
in release builds (console logger in debug, so dev traffic never pollutes
GA4). Firebase init is guarded — failure falls back to the debug logger
rather than blocking startup.

firebase.json keeps the existing Hosting config and gains the FlutterFire
platform section. Client config files are committed (they ship in the binary;
Firebase security is enforced by rules, not config secrecy).

flutter analyze clean, all 161 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 12:10:03 +09:00

71 lines
2.3 KiB
Dart

import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:path_provider/path_provider.dart';
import 'app.dart';
import 'data/content_repository.dart';
import 'data/remote/content_downloader.dart';
import 'data/save_repository.dart';
import 'firebase_options.dart';
import 'services/analytics_service.dart';
import 'services/firebase_analytics_backend.dart';
import 'state/providers.dart';
/// Remote content origin. Swap per environment with
/// --dart-define=CONTENT_BASE_URL=...; the default points at the production
/// Firebase Hosting site (owner setup pending).
const contentBaseUrl = String.fromEnvironment(
'CONTENT_BASE_URL',
defaultValue: 'https://block-seasons.web.app/content',
);
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final saveRepository = await SaveRepository.open();
// Analytics: real GA4 traffic flows only from release builds so development
// never pollutes production. If Firebase init fails (e.g. missing native
// config), fall back to the console logger rather than blocking startup.
AnalyticsService analytics;
try {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
analytics = AnalyticsService(
kReleaseMode ? FirebaseAnalyticsBackend() : DebugAnalyticsBackend(),
);
} catch (e) {
debugPrint('Firebase init failed, analytics disabled: $e');
analytics = AnalyticsService(DebugAnalyticsBackend());
}
ContentRepository contentRepository;
try {
final support = await getApplicationSupportDirectory();
final cacheDir = Directory('${support.path}/content');
contentRepository = ContentRepository(
cacheDir: cacheDir,
downloader: ContentDownloader(
baseUrl: contentBaseUrl,
cacheDir: cacheDir,
),
);
} catch (e) {
debugPrint('content cache unavailable, bundled only: $e');
contentRepository = ContentRepository();
}
runApp(ProviderScope(
overrides: [
saveRepositoryProvider.overrideWithValue(saveRepository),
contentRepositoryProvider.overrideWithValue(contentRepository),
analyticsProvider.overrideWithValue(analytics),
],
child: const BlockSeasonsApp(),
));
}