From 8d15fb69493defaac5edf4b877e406ccdcdce51a Mon Sep 17 00:00:00 2001 From: Allison Ryan Date: Thu, 17 Mar 2022 11:36:14 -0500 Subject: [PATCH] chore: connect to firebase --- ios/Flutter/Debug.xcconfig | 1 + ios/Flutter/Release.xcconfig | 1 + ios/Podfile | 41 +++++++++++++++++++++++++++ lib/app/view/app.dart | 35 ++++++++++++++--------- lib/bootstrap.dart | 13 +++++++-- lib/firebase_options.dart | 55 ++++++++++++++++++++++++++++++++++++ lib/main_development.dart | 6 +++- lib/main_production.dart | 6 +++- lib/main_staging.dart | 6 +++- pubspec.lock | 2 +- pubspec.yaml | 1 + test/app/view/app_test.dart | 14 ++++++++- 12 files changed, 161 insertions(+), 20 deletions(-) create mode 100644 ios/Podfile create mode 100644 lib/firebase_options.dart diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee8..ec97fc6f 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee8..c4855bfe 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 00000000..1e8c3c90 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/lib/app/view/app.dart b/lib/app/view/app.dart index cf6213e9..8de80730 100644 --- a/lib/app/view/app.dart +++ b/lib/app/view/app.dart @@ -8,29 +8,38 @@ // ignore_for_file: public_member_api_docs import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:leaderboard_repository/leaderboard_repository.dart'; import 'package:pinball/l10n/l10n.dart'; import 'package:pinball/landing/landing.dart'; class App extends StatelessWidget { - const App({Key? key}) : super(key: key); + const App({Key? key, required LeaderboardRepository leaderboardRepository}) + : _leaderboardRepository = leaderboardRepository, + super(key: key); + + final LeaderboardRepository _leaderboardRepository; @override Widget build(BuildContext context) { - return MaterialApp( - title: 'I/O Pinball', - theme: ThemeData( - appBarTheme: const AppBarTheme(color: Color(0xFF13B9FF)), - colorScheme: ColorScheme.fromSwatch( - accentColor: const Color(0xFF13B9FF), + return RepositoryProvider.value( + value: _leaderboardRepository, + child: MaterialApp( + title: 'I/O Pinball', + theme: ThemeData( + appBarTheme: const AppBarTheme(color: Color(0xFF13B9FF)), + colorScheme: ColorScheme.fromSwatch( + accentColor: const Color(0xFF13B9FF), + ), ), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], + supportedLocales: AppLocalizations.supportedLocales, + home: const LandingPage(), ), - localizationsDelegates: const [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - ], - supportedLocales: AppLocalizations.supportedLocales, - home: const LandingPage(), ); } } diff --git a/lib/bootstrap.dart b/lib/bootstrap.dart index 34fcc47a..7999d522 100644 --- a/lib/bootstrap.dart +++ b/lib/bootstrap.dart @@ -11,7 +11,10 @@ import 'dart:async'; import 'dart:developer'; import 'package:bloc/bloc.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/widgets.dart'; +import 'package:pinball/firebase_options.dart'; class AppBlocObserver extends BlocObserver { @override @@ -27,15 +30,21 @@ class AppBlocObserver extends BlocObserver { } } -Future bootstrap(FutureOr Function() builder) async { +Future bootstrap( + Future Function(FirebaseFirestore firestore) builder, +) async { + WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = (details) { log(details.exceptionAsString(), stackTrace: details.stack); }; + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); await runZonedGuarded( () async { await BlocOverrides.runZoned( - () async => runApp(await builder()), + () async => runApp(await builder(FirebaseFirestore.instance)), blocObserver: AppBlocObserver(), ); }, diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 00000000..2f47218b --- /dev/null +++ b/lib/firebase_options.dart @@ -0,0 +1,55 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + return web; + } + // ignore: missing_enum_constant_in_switch + switch (defaultTargetPlatform) { + case TargetPlatform.android: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for android - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.iOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyBgMVAvYccjNypCDdpW0ol6syCcISU2yjM', + appId: '1:725488140557:web:7c61a0755fc23436fe7044', + messagingSenderId: '725488140557', + projectId: 'pinball-dev', + authDomain: 'pinball-dev.firebaseapp.com', + storageBucket: 'pinball-dev.appspot.com', + measurementId: 'G-9NW8SZRFJR', + ); +} diff --git a/lib/main_development.dart b/lib/main_development.dart index 99927436..8673eff4 100644 --- a/lib/main_development.dart +++ b/lib/main_development.dart @@ -5,9 +5,13 @@ // license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT. +import 'package:leaderboard_repository/leaderboard_repository.dart'; import 'package:pinball/app/app.dart'; import 'package:pinball/bootstrap.dart'; void main() { - bootstrap(() => const App()); + bootstrap((firestore) async { + final leaderboardRepository = LeaderboardRepository(firestore); + return App(leaderboardRepository: leaderboardRepository); + }); } diff --git a/lib/main_production.dart b/lib/main_production.dart index 99927436..8673eff4 100644 --- a/lib/main_production.dart +++ b/lib/main_production.dart @@ -5,9 +5,13 @@ // license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT. +import 'package:leaderboard_repository/leaderboard_repository.dart'; import 'package:pinball/app/app.dart'; import 'package:pinball/bootstrap.dart'; void main() { - bootstrap(() => const App()); + bootstrap((firestore) async { + final leaderboardRepository = LeaderboardRepository(firestore); + return App(leaderboardRepository: leaderboardRepository); + }); } diff --git a/lib/main_staging.dart b/lib/main_staging.dart index 99927436..8673eff4 100644 --- a/lib/main_staging.dart +++ b/lib/main_staging.dart @@ -5,9 +5,13 @@ // license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT. +import 'package:leaderboard_repository/leaderboard_repository.dart'; import 'package:pinball/app/app.dart'; import 'package:pinball/bootstrap.dart'; void main() { - bootstrap(() => const App()); + bootstrap((firestore) async { + final leaderboardRepository = LeaderboardRepository(firestore); + return App(leaderboardRepository: leaderboardRepository); + }); } diff --git a/pubspec.lock b/pubspec.lock index 79aa7138..71647cae 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -79,7 +79,7 @@ packages: source: hosted version: "1.1.0" cloud_firestore: - dependency: transitive + dependency: "direct main" description: name: cloud_firestore url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index abd78157..81b056b3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,6 +8,7 @@ environment: dependencies: bloc: ^8.0.2 + cloud_firestore: ^3.1.10 equatable: ^2.0.3 flame: ^1.1.0-releasecandidate.5 flame_bloc: ^1.2.0-releasecandidate.5 diff --git a/test/app/view/app_test.dart b/test/app/view/app_test.dart index d0fd36b9..5a6a249f 100644 --- a/test/app/view/app_test.dart +++ b/test/app/view/app_test.dart @@ -6,13 +6,25 @@ // https://opensource.org/licenses/MIT. import 'package:flutter_test/flutter_test.dart'; +import 'package:leaderboard_repository/leaderboard_repository.dart'; +import 'package:mocktail/mocktail.dart'; import 'package:pinball/app/app.dart'; import 'package:pinball/landing/landing.dart'; +class MockLeaderboardRepository extends Mock implements LeaderboardRepository {} + void main() { group('App', () { + late LeaderboardRepository leaderboardRepository; + + setUp(() { + leaderboardRepository = MockLeaderboardRepository(); + }); + testWidgets('renders LandingPage', (tester) async { - await tester.pumpWidget(const App()); + await tester.pumpWidget( + App(leaderboardRepository: leaderboardRepository), + ); expect(find.byType(LandingPage), findsOneWidget); }); });