# Authentication BLoC

Style: Wyatt Analysis SDK: Flutter

Authentication Bloc for Flutter. ## Features * ๐Ÿง Wyatt Architecture * ๐Ÿงฑ Entities - Account -> Contains account information from provider. - Session -> Contains account and associated data retrieved from an external source. - AuthenticationChangeEvent -> Describes an event in authentication change (sign in, sign up, sign out, etc...) - SessionWrapper -> Contains latest authentication change event and session. * ๐Ÿ”‘ Powerful and secured authentication repository * ๐Ÿ”ฅ Multiple data sources - Mock - Firebase * ๐ŸงŠ Cubits, why make it complicated when you can make it simple? - Goes to the essential. * ๐Ÿ“ Consistent - Every class have same naming convention * ๐Ÿงช Tested * ๐Ÿ“š Documented: [available here](./doc/api/index.md) ## Getting started Simply add `wyatt_authentication_bloc` in `pubspec.yaml` , then ```dart import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart'; ``` ### Data source The first step is to provide a data source. ```dart getIt.registerLazySingleton>( () => AuthenticationFirebaseDataSourceImpl( firebaseAuth: FirebaseAuth.instance, googleSignIn: GoogleSignIn(clientId: DefaultFirebaseOptions.ios.iosClientId)), ); ``` > Here we use GetIt (see example project) ### Repository Then you can configure your repository. ```dart final AuthenticationRepository authenticationRepository = AuthenticationRepositoryImpl( authenticationRemoteDataSource: getIt>(), customPasswordValidator: const CustomPassword.pure(), extraSignUpInputs: [ FormInput( AuthFormField.confirmPassword, const ConfirmedPassword.pure(), metadata: const FormInputMetadata(export: false), ), ], ); ``` > Here we pass some extra inputs for the sign up, and a custom password validator. ### Cubits It is necessary to implement each cubit. Don't panic, most of the work is already done ๐Ÿ˜Š you just have to customize the logic of these. In each of these cubits it is necessary to overload the various callbacks. > Here the associated data `Data` is a `int` #### Authentication In the authentication are managed, the refresh, the deletion of account or the disconnection. ```dart class ExampleAuthenticationCubit extends AuthenticationCubit { ExampleAuthenticationCubit({required super.authenticationRepository}); @override FutureOrResult onReauthenticate(Result result) async { // TODO } @override FutureOrResult onRefresh(Result result) { // TODO } @override FutureOrResult onSignInFromCache(SessionWrapper wrapper) { // TODO } @override FutureOrResult onSignOut() { // TODO } @override FutureOrResult onDelete() { // TODO } } ``` #### Sign Up ```dart class ExampleSignUpCubit extends SignUpCubit { ExampleSignUpCubit({ required super.authenticationRepository, }); @override FutureOrResult onSignUpWithEmailAndPassword(Result result, WyattForm form) async { // TODO } } ``` #### Sign In ```dart class ExampleSignInCubit extends SignInCubit { ExampleSignInCubit({ required super.authenticationRepository, }); @override FutureOrResult onSignInWithEmailAndPassword(Result result, WyattForm form) { // TODO } @override FutureOrResult onSignInAnonymously(Result result, WyattForm form) { // TODO } @override FutureOrResult onSignInWithGoogle(Result result, WyattForm form) { // TODO } } ``` After setting up all these cubits you can provide them in the application. And that's it! ```dart BlocProvider>( create: (_) => ExampleSignUpCubit( authenticationRepository: authenticationRepository, ), ), BlocProvider>( create: (_) => ExampleSignInCubit( authenticationRepository: authenticationRepository, ), ), ``` ### Widgets Widgets are provided to make your life easier. Starting with the `AuthenticationBuilder` which allows you to build according to the authentication state. ```dart AuthenticationBuilder( authenticated: (context, sessionWrapper) => Text( 'Logged as ${sessionWrapper.session?.account.email} | GeneratedId is ${sessionWrapper.session?.data}'), unauthenticated: (context) => const Text('Not logged (unauthenticated)'), unknown: (context) => const Text('Not logged (unknown)'), ), ``` A `BuildContext` extension is also available to access certain attributes more quickly. ```dart Text('Home | ${context.account, int>()?.email}'), ``` Listeners are used to listen to the status of the sign in and sign up forms. ```dart return SignInListener( onError: (context, status, errorMessage) => ScaffoldMessenger.of(context) ..hideCurrentSnackBar() ..showSnackBar( SnackBar(content: Text(errorMessage ?? 'Sign In Failure')), ), child: ... ); ```