feat(authentication): add google sign in in signIn cubit

This commit is contained in:
Hugo Pointcheval 2022-12-13 00:36:20 -05:00
parent 197c5d54e6
commit 1a3631f691
Signed by: hugo
GPG Key ID: A9E8E9615379254F
13 changed files with 251 additions and 93 deletions

View File

@ -44,6 +44,4 @@ app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
firebase_options.dart
/android/app/release

View File

@ -4,7 +4,7 @@
* -----
* File: launch.json
* Created Date: 19/08/2022 15:12:25
* Last Modified: 19/08/2022 15:22:02
* Last Modified: Tue Dec 13 2022
* -----
* Copyright (c) 2022
*/
@ -15,11 +15,18 @@
"version": "0.2.0",
"configurations": [
{
"name": "example_router",
"name": "Mock",
"request": "launch",
"type": "dart",
"program": "lib/main.dart",
"flutterMode": "debug"
},
{
"name": "Firebase",
"request": "launch",
"type": "dart",
"program": "lib/main_firebase.dart",
"flutterMode": "debug"
}
]
}

View File

@ -5,41 +5,30 @@ PODS:
- AppAuth/Core (1.6.0)
- AppAuth/ExternalUserAgent (1.6.0):
- AppAuth/Core
- FBAEMKit (14.1.0):
- FBSDKCoreKit_Basics (= 14.1.0)
- FBSDKCoreKit (14.1.0):
- FBAEMKit (= 14.1.0)
- FBSDKCoreKit_Basics (= 14.1.0)
- FBSDKCoreKit_Basics (14.1.0)
- FBSDKLoginKit (14.1.0):
- FBSDKCoreKit (= 14.1.0)
- Firebase/Auth (10.0.0):
- Firebase/Auth (10.3.0):
- Firebase/CoreOnly
- FirebaseAuth (~> 10.0.0)
- Firebase/CoreOnly (10.0.0):
- FirebaseCore (= 10.0.0)
- firebase_auth (4.1.1):
- Firebase/Auth (= 10.0.0)
- FirebaseAuth (~> 10.3.0)
- Firebase/CoreOnly (10.3.0):
- FirebaseCore (= 10.3.0)
- firebase_auth (4.2.0):
- Firebase/Auth (= 10.3.0)
- firebase_core
- Flutter
- firebase_core (2.1.1):
- Firebase/CoreOnly (= 10.0.0)
- firebase_core (2.4.0):
- Firebase/CoreOnly (= 10.3.0)
- Flutter
- FirebaseAuth (10.0.0):
- FirebaseAuth (10.3.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
- GoogleUtilities/Environment (~> 7.8)
- GTMSessionFetcher/Core (~> 2.1)
- FirebaseCore (10.0.0):
- GTMSessionFetcher/Core (< 4.0, >= 2.1)
- FirebaseCore (10.3.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
- FirebaseCoreInternal (10.1.0):
- FirebaseCoreInternal (10.3.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- Flutter (1.0.0)
- flutter_facebook_auth (4.4.1):
- FBSDKLoginKit (= 14.1.0)
- Flutter
- google_sign_in_ios (0.0.1):
- Flutter
- GoogleSignIn (~> 6.2)
@ -47,47 +36,36 @@ PODS:
- AppAuth (~> 1.5)
- GTMAppAuth (~> 1.3)
- GTMSessionFetcher/Core (< 3.0, >= 1.1)
- GoogleUtilities/AppDelegateSwizzler (7.8.0):
- GoogleUtilities/AppDelegateSwizzler (7.10.0):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (7.8.0):
- GoogleUtilities/Environment (7.10.0):
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.8.0):
- GoogleUtilities/Logger (7.10.0):
- GoogleUtilities/Environment
- GoogleUtilities/Network (7.8.0):
- GoogleUtilities/Network (7.10.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.8.0)"
- GoogleUtilities/Reachability (7.8.0):
- "GoogleUtilities/NSData+zlib (7.10.0)"
- GoogleUtilities/Reachability (7.10.0):
- GoogleUtilities/Logger
- GTMAppAuth (1.3.1):
- AppAuth/Core (~> 1.6)
- GTMSessionFetcher/Core (< 3.0, >= 1.5)
- GTMSessionFetcher/Core (2.1.0)
- GTMSessionFetcher/Core (2.3.0)
- PromisesObjC (2.1.1)
- sign_in_with_apple (0.0.1):
- Flutter
- twitter_login (0.0.1):
- Flutter
DEPENDENCIES:
- firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- Flutter (from `Flutter`)
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`)
- sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
- twitter_login (from `.symlinks/plugins/twitter_login/ios`)
SPEC REPOS:
trunk:
- AppAuth
- FBAEMKit
- FBSDKCoreKit
- FBSDKCoreKit_Basics
- FBSDKLoginKit
- Firebase
- FirebaseAuth
- FirebaseCore
@ -105,37 +83,24 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_core/ios"
Flutter:
:path: Flutter
flutter_facebook_auth:
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
google_sign_in_ios:
:path: ".symlinks/plugins/google_sign_in_ios/ios"
sign_in_with_apple:
:path: ".symlinks/plugins/sign_in_with_apple/ios"
twitter_login:
:path: ".symlinks/plugins/twitter_login/ios"
SPEC CHECKSUMS:
AppAuth: 8fca6b5563a5baef2c04bee27538025e4ceb2add
FBAEMKit: a899515e45476027f73aef377b5cffadcd56ca3a
FBSDKCoreKit: 24f8bc8d3b5b2a8c5c656a1329492a12e8efa792
FBSDKCoreKit_Basics: 6e578c9bdc7aa1365dbbbde633c9ebb536bcaa98
FBSDKLoginKit: 787de205d524c3a4b17d527916f1d066e4361660
Firebase: 1b810f3d0c0532e27a48f1961f8c0400a668a2cf
firebase_auth: dd33e93fce72a1c72040f7380dacf06e89db5705
firebase_core: 5c0bb0ca7d0e70480a68a6e9ad9bf55d1edd5305
FirebaseAuth: 493382cf533cc45e2862b00e9aa4cfe4c98daf71
FirebaseCore: 97f48a3a567a72b8d4daa0f03c3aadb78df4e995
FirebaseCoreInternal: 96d75228e10fd369564da51bd898414eb0f54df5
Firebase: f92fc551ead69c94168d36c2b26188263860acd9
firebase_auth: 579a0dc15451491cc83fccaa5102296635f24938
firebase_core: 6f2f753e316765799d88568232ed59e300ff53db
FirebaseAuth: 0e415d29d846c1dce2fb641e46f35e9888d9bec6
FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a
FirebaseCoreInternal: 29b76f784d607df8b2a1259d73c3f04f1210137b
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_facebook_auth: 361ac7a57263ebf327f26089507ead0d66558ee8
google_sign_in_ios: 4f85eb9f937450765c8573bb85fd8cd6a5af675c
GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
GoogleUtilities: 1d20a6ad97ef46f67bbdec158ce00563a671ebb7
GoogleUtilities: bad72cb363809015b1f7f19beb1f1cd23c589f95
GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
GTMSessionFetcher: ffbb25ec00ebcb5201adab0a56d808f6f1902d9f
GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440
twitter_login: 2794db69b7640681171b17b3c2c84ad9dfb4a57f
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3

View File

@ -28,6 +28,17 @@
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.405351917235-2jv4ff02kovoim58f8d6d0rsa14apgkj</string>
</array>
</dict>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>

View File

@ -1,7 +1,7 @@
{
"file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:136771801992:ios:bcdca68d2b7d227097203d",
"FIREBASE_PROJECT_ID": "tchat-beta",
"GCM_SENDER_ID": "136771801992"
"GOOGLE_APP_ID": "1:405351917235:ios:869f0ad8ace08db899f2c6",
"FIREBASE_PROJECT_ID": "meerabel-dev",
"GCM_SENDER_ID": "405351917235"
}

View File

@ -18,9 +18,47 @@ import 'dart:async';
import 'package:example_router/core/dependency_injection/get_it.dart';
import 'package:example_router/core/utils/app_bloc_observer.dart';
import 'package:example_router/firebase_options.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class MockSettings {
static MockSettings? _instance;
/// Data source mode
late bool enable = false;
MockSettings._(this.enable);
factory MockSettings.enable() {
_instance ??= MockSettings._(true);
if (_instance!.enable != true) {
throw Exception('Mock already initialized in: ${_instance!.enable}');
}
return _instance!;
}
factory MockSettings.disable() {
_instance ??= MockSettings._(false);
if (_instance!.enable != false) {
throw Exception('Mock already initialized in: ${_instance!.enable}');
}
return _instance!;
}
static bool isEnable() {
if (_instance == null) {
throw Exception('MockSettings not initialized!');
}
return _instance!.enable == true;
}
static bool isDisable() {
return !isEnable();
}
}
Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
await runZonedGuarded(
() async {
@ -30,6 +68,12 @@ Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
FlutterError.onError = (details) {
debugPrint(details.toString());
};
if (MockSettings.isDisable()) {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
}
await GetItInitializer.init();
runApp(await builder());

View File

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:example_router/bootstrap.dart';
import 'package:example_router/firebase_options.dart';
import 'package:get_it/get_it.dart';
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
@ -24,28 +26,32 @@ abstract class GetItInitializer {
static Future<void> init() async {
getIt
..registerLazySingleton<AuthenticationRemoteDataSource>(
() => AuthenticationMockDataSourceImpl(registeredAccounts: [
Pair(
AccountModel(
uid: '1',
emailVerified: true,
isAnonymous: false,
providerId: 'wyatt',
email: 'toto@test.fr',
MockSettings.isEnable()
? () => AuthenticationMockDataSourceImpl(registeredAccounts: [
Pair(
AccountModel(
uid: '1',
emailVerified: true,
isAnonymous: false,
providerId: 'wyatt',
email: 'toto@test.fr',
),
'toto1234',
),
Pair(
AccountModel(
uid: '2',
emailVerified: false,
isAnonymous: false,
providerId: 'wyatt',
email: 'tata@test.fr',
),
'tata1234',
),
])
: () => AuthenticationFirebaseDataSourceImpl(
googleSignIn: GoogleSignIn(clientId: DefaultFirebaseOptions.ios.iosClientId)
),
'toto1234',
),
Pair(
AccountModel(
uid: '2',
emailVerified: false,
isAnonymous: false,
providerId: 'wyatt',
email: 'tata@test.fr',
),
'tata1234',
),
]),
)
..registerLazySingleton<AuthenticationCacheDataSource<int>>(
() => AuthenticationCacheDataSourceImpl<int>(),

View File

@ -0,0 +1,65 @@
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
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) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
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:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyDDmtf0KN7Xw12_pqUsxoBfAxMuvCMmMmk',
appId: '1:405351917235:ios:869f0ad8ace08db899f2c6',
messagingSenderId: '405351917235',
projectId: 'meerabel-dev',
storageBucket: 'meerabel-dev.appspot.com',
androidClientId: '405351917235-4g1dh3475tq6t1sa2qoh7ol60nf4ta05.apps.googleusercontent.com',
iosClientId: '405351917235-2jv4ff02kovoim58f8d6d0rsa14apgkj.apps.googleusercontent.com',
iosBundleId: 'com.example.exampleRouter',
);
}

View File

@ -18,5 +18,6 @@ import 'package:example_router/bootstrap.dart';
import 'package:example_router/presentation/features/app/app.dart';
void main() {
MockSettings.enable();
bootstrap(App.new);
}

View File

@ -0,0 +1,23 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:example_router/bootstrap.dart';
import 'package:example_router/presentation/features/app/app.dart';
void main() {
MockSettings.disable();
bootstrap(App.new);
}

View File

@ -94,6 +94,22 @@ class _SignInAnonymouslyButton extends StatelessWidget {
}
}
class _SignInWithGoogleButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SubmitBuilder<SignInCubit<int>>(
builder: ((context, cubit, status) {
return status.isSubmissionInProgress
? const CircularProgressIndicator()
: ElevatedButton(
onPressed: () => cubit.signInWithGoogle(),
child: const Text('Sign in Google'),
);
}),
);
}
}
class SignInForm extends StatelessWidget {
const SignInForm({Key? key}) : super(key: key);
@ -116,6 +132,8 @@ class SignInForm extends StatelessWidget {
_SignInButton(),
const SizedBox(height: 16),
_SignInAnonymouslyButton(),
const SizedBox(height: 16),
_SignInWithGoogleButton(),
],
),
),

View File

@ -112,7 +112,7 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
uid: 'mock-id-anom',
emailVerified: false,
isAnonymous: true,
providerId: 'wyatt',
providerId: 'wyatt-studio.fr',
creationTime: creation,
lastSignInTime: creation,
isNewUser: creation == creation,
@ -131,7 +131,7 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource {
uid: 'mock-id-google',
emailVerified: true,
isAnonymous: false,
providerId: 'google',
providerId: 'google.com',
creationTime: creation,
lastSignInTime: creation,
isNewUser: creation == creation,

View File

@ -205,4 +205,24 @@ class SignInCubit<Extra> extends FormDataCubit<SignInState> {
),
);
}
FutureOr<void> signInWithGoogle() async {
if (state.status.isSubmissionInProgress) {
return;
}
// TODO(wyatt): maybe emit new state (to not carry an old errorMessage)
emit(state.copyWith(status: FormStatus.submissionInProgress));
final uid = await _authenticationRepository.signInWithGoogle();
emit(
uid.fold(
(value) => state.copyWith(status: FormStatus.submissionSuccess),
(error) => state.copyWith(
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
}