From c7b241de2d5d8a7f925c15bac31b26ffc263ac46 Mon Sep 17 00:00:00 2001 From: Hugo Pointcheval Date: Mon, 12 Dec 2022 23:16:10 -0500 Subject: [PATCH] feat(authentication): add google sign_in support (closes #59) --- ...hentication_firebase_data_source_impl.dart | 34 ++++++++++++++++++- .../authentication_mock_data_source_impl.dart | 19 +++++++++++ .../authentication_repository_impl.dart | 11 ++++++ .../authentication_remote_data_source.dart | 2 ++ .../authentication_repository.dart | 7 ++++ 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_firebase_data_source_impl.dart b/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_firebase_data_source_impl.dart index e24fb231..78c4bf79 100644 --- a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_firebase_data_source_impl.dart +++ b/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_firebase_data_source_impl.dart @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import 'package:firebase_auth/firebase_auth.dart'; import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; @@ -182,6 +181,39 @@ class AuthenticationFirebaseDataSourceImpl } } + @override + Future signInWithGoogle() async { + try { + // Trigger the authentication flow + final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn(); + + // Obtain the auth details from the request + final GoogleSignInAuthentication? googleAuth = + await googleUser?.authentication; + + // Create a new credential + final credential = GoogleAuthProvider.credential( + accessToken: googleAuth?.accessToken, + idToken: googleAuth?.idToken, + ); + + final userCredential = + await _firebaseAuth.signInWithCredential(credential); + + _latestCreds = userCredential; + final user = userCredential.user; + if (user.isNotNull) { + return _mapper(user!); + } else { + throw Exception(); // Get caught just after. + } + } on FirebaseAuthException catch (e) { + throw SignInWithGoogleFailureFirebase.fromCode(e.code); + } catch (_) { + throw SignInWithGoogleFailureFirebase(); + } + } + @override Future verifyPasswordResetCode({required String code}) async { try { diff --git a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_mock_data_source_impl.dart b/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_mock_data_source_impl.dart index e1478f88..cec578a5 100644 --- a/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_mock_data_source_impl.dart +++ b/packages/wyatt_authentication_bloc/lib/src/data/data_sources/remote/authentication_mock_data_source_impl.dart @@ -123,6 +123,25 @@ class AuthenticationMockDataSourceImpl extends AuthenticationRemoteDataSource { return Future.value(mock); } + @override + Future signInWithGoogle() async { + await _randomDelay(); + final creation = DateTime.now(); + final mock = AccountModel( + uid: 'mock-id-google', + emailVerified: true, + isAnonymous: false, + providerId: 'google', + creationTime: creation, + lastSignInTime: creation, + isNewUser: creation == creation, + ); + _streamAccount.add(mock); + _connectedMock = _connectedMock?.copyWith(left: mock); + _lastSignInTime = DateTime.now(); + return Future.value(mock); + } + @override Future signInWithEmailAndPassword({ required String email, diff --git a/packages/wyatt_authentication_bloc/lib/src/data/repositories/authentication_repository_impl.dart b/packages/wyatt_authentication_bloc/lib/src/data/repositories/authentication_repository_impl.dart index 294e1096..7bbc7954 100644 --- a/packages/wyatt_authentication_bloc/lib/src/data/repositories/authentication_repository_impl.dart +++ b/packages/wyatt_authentication_bloc/lib/src/data/repositories/authentication_repository_impl.dart @@ -295,6 +295,17 @@ class AuthenticationRepositoryImpl (error) => error, ); + @override + FutureOrResult signInWithGoogle() => + Result.tryCatchAsync( + () async { + final account = + await _authenticationRemoteDataSource.signInWithGoogle(); + return account; + }, + (error) => error, + ); + @override FutureOrResult verifyPasswordResetCode({required String code}) => Result.tryCatchAsync( diff --git a/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/remote/authentication_remote_data_source.dart b/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/remote/authentication_remote_data_source.dart index b379de92..8205bd8d 100644 --- a/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/remote/authentication_remote_data_source.dart +++ b/packages/wyatt_authentication_bloc/lib/src/domain/data_sources/remote/authentication_remote_data_source.dart @@ -49,6 +49,8 @@ abstract class AuthenticationRemoteDataSource extends BaseRemoteDataSource { Future signInAnonymously(); + Future signInWithGoogle(); + Future updateEmail({required String email}); Future updatePassword({required String password}); diff --git a/packages/wyatt_authentication_bloc/lib/src/domain/repositories/authentication_repository.dart b/packages/wyatt_authentication_bloc/lib/src/domain/repositories/authentication_repository.dart index 56f1697b..027c7525 100644 --- a/packages/wyatt_authentication_bloc/lib/src/domain/repositories/authentication_repository.dart +++ b/packages/wyatt_authentication_bloc/lib/src/domain/repositories/authentication_repository.dart @@ -73,6 +73,13 @@ abstract class AuthenticationRepository extends BaseRepository { /// {@endtemplate} FutureOrResult signInAnonymously(); + /// {@template signin_google} + /// Starts the Sign In with Google Flow. + /// + /// Throws a SignInWithGoogleFailureInterface if an exception occurs. + /// {@endtemplate} + FutureOrResult signInWithGoogle(); + /// {@template signin_pwd} /// Signs in with the provided [email] and [password]. ///