Skip to content

Commit

Permalink
Merge branch 'master' into firebase-apple
Browse files Browse the repository at this point in the history
  • Loading branch information
marcossevilla authored Oct 6, 2021
2 parents 29455ec + a3a9b2d commit f3718c7
Show file tree
Hide file tree
Showing 13 changed files with 195 additions and 17 deletions.
10 changes: 10 additions & 0 deletions examples/flutter_firebase_login/lib/login/cubit/login_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ class LoginCubit extends Cubit<LoginState> {
password: state.password.value,
);
emit(state.copyWith(status: FormzStatus.submissionSuccess));
} on LogInWithEmailAndPasswordFailure catch (e) {
emit(state.copyWith(
errorMessage: e.message,
status: FormzStatus.submissionFailure,
));
} catch (_) {
emit(state.copyWith(status: FormzStatus.submissionFailure));
}
Expand All @@ -46,6 +51,11 @@ class LoginCubit extends Cubit<LoginState> {
try {
await _authenticationRepository.logInWithGoogle();
emit(state.copyWith(status: FormzStatus.submissionSuccess));
} on LogInWithGoogleFailure catch (e) {
emit(state.copyWith(
errorMessage: e.message,
status: FormzStatus.submissionFailure,
));
} catch (_) {
emit(state.copyWith(status: FormzStatus.submissionFailure));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ class LoginState extends Equatable {
this.email = const Email.pure(),
this.password = const Password.pure(),
this.status = FormzStatus.pure,
this.errorMessage,
});

final Email email;
final Password password;
final FormzStatus status;
final String? errorMessage;

@override
List<Object> get props => [email, password, status];
Expand All @@ -18,11 +20,13 @@ class LoginState extends Equatable {
Email? email,
Password? password,
FormzStatus? status,
String? errorMessage,
}) {
return LoginState(
email: email ?? this.email,
password: password ?? this.password,
status: status ?? this.status,
errorMessage: errorMessage ?? this.errorMessage,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ class LoginForm extends StatelessWidget {
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(
const SnackBar(content: Text('Authentication Failure')),
SnackBar(
content: Text(state.errorMessage ?? 'Authentication Failure'),
),
);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ class SignUpCubit extends Cubit<SignUpState> {
password: state.password.value,
);
emit(state.copyWith(status: FormzStatus.submissionSuccess));
} on Exception {
} on SignUpWithEmailAndPasswordFailure catch (e) {
emit(state.copyWith(
errorMessage: e.message,
status: FormzStatus.submissionFailure,
));
} catch (_) {
emit(state.copyWith(status: FormzStatus.submissionFailure));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ class SignUpState extends Equatable {
this.password = const Password.pure(),
this.confirmedPassword = const ConfirmedPassword.pure(),
this.status = FormzStatus.pure,
this.errorMessage,
});

final Email email;
final Password password;
final ConfirmedPassword confirmedPassword;
final FormzStatus status;
final String? errorMessage;

@override
List<Object> get props => [email, password, confirmedPassword, status];
Expand All @@ -23,12 +25,14 @@ class SignUpState extends Equatable {
Password? password,
ConfirmedPassword? confirmedPassword,
FormzStatus? status,
String? errorMessage,
}) {
return SignUpState(
email: email ?? this.email,
password: password ?? this.password,
confirmedPassword: confirmedPassword ?? this.confirmedPassword,
status: status ?? this.status,
errorMessage: errorMessage ?? this.errorMessage,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class SignUpForm extends StatelessWidget {
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(
const SnackBar(content: Text('Sign Up Failure')),
SnackBar(content: Text(state.errorMessage ?? 'Sign Up Failure')),
);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,148 @@ import 'package:authentication_repository/authentication_repository.dart';
import 'package:authentication_repository/src/crypto_api.dart';
import 'package:cache/cache.dart';
import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;
import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:google_sign_in/google_sign_in.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'package:meta/meta.dart';

/// {@template sign_up_with_email_and_password_failure}
/// Thrown if during the sign up process if a failure occurs.
class SignUpFailure implements Exception {}
/// {@endtemplate}
class SignUpWithEmailAndPasswordFailure implements Exception {
/// {@macro sign_up_with_email_and_password_failure}
const SignUpWithEmailAndPasswordFailure([
this.message = 'An unknown exception occurred.',
]);

/// Create an authentication message
/// from a firebase authentication exception code.
/// https://pub.dev/documentation/firebase_auth/latest/firebase_auth/FirebaseAuth/createUserWithEmailAndPassword.html
factory SignUpWithEmailAndPasswordFailure.fromCode(String code) {
switch (code) {
case 'invalid-email':
return const SignUpWithEmailAndPasswordFailure(
'Email is not valid or badly formatted.',
);
case 'user-disabled':
return const SignUpWithEmailAndPasswordFailure(
'This user has been disabled. Please contact support for help.',
);
case 'email-already-in-use':
return const SignUpWithEmailAndPasswordFailure(
'An account already exists for that email.',
);
case 'operation-not-allowed':
return const SignUpWithEmailAndPasswordFailure(
'Operation is not allowed. Please contact support.',
);
case 'weak-password':
return const SignUpWithEmailAndPasswordFailure(
'Please enter a stronger password.',
);
default:
return const SignUpWithEmailAndPasswordFailure();
}
}

/// The associated error message.
final String message;
}

/// {@template log_in_with_email_and_password_failure}
/// Thrown during the login process if a failure occurs.
class LogInWithEmailAndPasswordFailure implements Exception {}
/// https://pub.dev/documentation/firebase_auth/latest/firebase_auth/FirebaseAuth/signInWithEmailAndPassword.html
/// {@endtemplate}
class LogInWithEmailAndPasswordFailure implements Exception {
/// {@macro log_in_with_email_and_password_failure}
const LogInWithEmailAndPasswordFailure([
this.message = 'An unknown exception occurred.',
]);

/// Create an authentication message
/// from a firebase authentication exception code.
factory LogInWithEmailAndPasswordFailure.fromCode(String code) {
switch (code) {
case 'invalid-email':
return const LogInWithEmailAndPasswordFailure(
'Email is not valid or badly formatted.',
);
case 'user-disabled':
return const LogInWithEmailAndPasswordFailure(
'This user has been disabled. Please contact support for help.',
);
case 'user-not-found':
return const LogInWithEmailAndPasswordFailure(
'Email is not found, please create an account.',
);
case 'wrong-password':
return const LogInWithEmailAndPasswordFailure(
'Incorrect password, please try again.',
);
default:
return const LogInWithEmailAndPasswordFailure();
}
}

/// The associated error message.
final String message;
}

/// {@template log_in_with_google_failure}
/// Thrown during the sign in with google process if a failure occurs.
class LogInWithGoogleFailure implements Exception {}
/// https://pub.dev/documentation/firebase_auth/latest/firebase_auth/FirebaseAuth/signInWithCredential.html
/// {@endtemplate}
class LogInWithGoogleFailure implements Exception {
/// {@macro log_in_with_google_failure}
const LogInWithGoogleFailure([
this.message = 'An unknown exception occurred.',
]);

/// Create an authentication message
/// from a firebase authentication exception code.
factory LogInWithGoogleFailure.fromCode(String code) {
switch (code) {
case 'account-exists-with-different-credential':
return const LogInWithGoogleFailure(
'Account exists with different credentials.',
);
case 'invalid-credential':
return const LogInWithGoogleFailure(
'The credential received is malformed or has expired.',
);
case 'operation-not-allowed':
return const LogInWithGoogleFailure(
'Operation is not allowed. Please contact support.',
);
case 'user-disabled':
return const LogInWithGoogleFailure(
'This user has been disabled. Please contact support for help.',
);
case 'user-not-found':
return const LogInWithGoogleFailure(
'Email is not found, please create an account.',
);
case 'wrong-password':
return const LogInWithGoogleFailure(
'Incorrect password, please try again.',
);
case 'invalid-verification-code':
return const LogInWithGoogleFailure(
'The credential verification code received is invalid.',
);
case 'invalid-verification-id':
return const LogInWithGoogleFailure(
'The credential verification ID received is invalid.',
);
default:
return const LogInWithGoogleFailure();
}
}

/// The associated error message.
final String message;
}

/// Thrown during the sign in with apple process if a failure occurs.
class LogInWithAppleFailure implements Exception {}
Expand Down Expand Up @@ -75,15 +204,17 @@ class AuthenticationRepository {

/// Creates a new user with the provided [email] and [password].
///
/// Throws a [SignUpFailure] if an exception occurs.
/// Throws a [SignUpWithEmailAndPasswordFailure] if an exception occurs.
Future<void> signUp({required String email, required String password}) async {
try {
await _firebaseAuth.createUserWithEmailAndPassword(
email: email,
password: password,
);
} on Exception {
throw SignUpFailure();
} on FirebaseAuthException catch (e) {
throw SignUpWithEmailAndPasswordFailure.fromCode(e.code);
} catch (_) {
throw const SignUpWithEmailAndPasswordFailure();
}
}

Expand All @@ -109,8 +240,10 @@ class AuthenticationRepository {
}

await _firebaseAuth.signInWithCredential(credential);
} on FirebaseAuthException catch (e) {
throw LogInWithGoogleFailure.fromCode(e.code);
} catch (_) {
throw LogInWithGoogleFailure();
throw const LogInWithGoogleFailure();
}
}

Expand Down Expand Up @@ -158,8 +291,10 @@ class AuthenticationRepository {
email: email,
password: password,
);
} on Exception {
throw LogInWithEmailAndPasswordFailure();
} on FirebaseAuthException catch (e) {
throw LogInWithEmailAndPasswordFailure.fromCode(e.code);
} catch (_) {
throw const LogInWithEmailAndPasswordFailure();
}
}

Expand All @@ -173,7 +308,7 @@ class AuthenticationRepository {
_firebaseAuth.signOut(),
_googleSignIn.signOut(),
]);
} on Exception {
} catch (_) {
throw LogOutFailure();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ void main() {
);
});

test('throws SignUpFailure when createUserWithEmailAndPassword throws',
() async {
test(
'throws SignUpWithEmailAndPasswordFailure '
'when createUserWithEmailAndPassword throws', () async {
when(
() => firebaseAuth.createUserWithEmailAndPassword(
email: any(named: 'email'),
Expand All @@ -144,7 +145,7 @@ void main() {
).thenThrow(Exception());
expect(
authenticationRepository.signUp(email: email, password: password),
throwsA(isA<SignUpFailure>()),
throwsA(isA<SignUpWithEmailAndPasswordFailure>()),
);
});
});
Expand Down
4 changes: 4 additions & 0 deletions packages/angular_bloc/lib/angular_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/// Angular components that make it easy to implement the BLoC design pattern.
/// Built to be used with the [bloc state management package](https://pub.dev/packages/bloc).
///
/// Get started at [bloclibrary.dev](https://bloclibrary.dev) 🚀
library angular_dart;

export 'package:bloc/bloc.dart';
Expand Down
5 changes: 4 additions & 1 deletion packages/bloc_tools/lib/bloc_tools.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/// Tools for building applications using the bloc state management library.
/// Tools for building applications using the
/// [bloc state management library](https://pub.dev/packages/bloc).
///
/// ```sh
/// # activate bloc_tools
Expand All @@ -7,4 +8,6 @@
/// # see usage
/// bloc --help
/// ```
///
/// Get started at [bloclibrary.dev](https://bloclibrary.dev) 🚀
library bloc_tools;
4 changes: 4 additions & 0 deletions packages/flutter_bloc/lib/flutter_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/// Flutter widgets that make it easy to implement the BLoC design pattern.
/// Built to be used with the [bloc state management package](https://pub.dev/packages/bloc).
///
/// Get started at [bloclibrary.dev](https://bloclibrary.dev) 🚀
library flutter_bloc;

export 'package:bloc/bloc.dart';
Expand Down
2 changes: 2 additions & 0 deletions packages/hydrated_bloc/lib/hydrated_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/// An extension to [package:bloc](https://github.com/felangel/bloc)
/// which automatically persists and restores bloc and cubit states.
/// Built to work with [package:bloc](https://pub.dev/packages/bloc).
///
/// Get started at [bloclibrary.dev](https://bloclibrary.dev) 🚀
library hydrated_bloc;

export 'package:bloc/bloc.dart';
Expand Down
4 changes: 4 additions & 0 deletions packages/replay_bloc/lib/replay_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/// An extension to the [bloc state management library](https://pub.dev/packages/bloc)
/// which adds support for undo and redo.
///
/// Get started at [bloclibrary.dev](https://bloclibrary.dev) 🚀
library replay_bloc;

export 'package:bloc/bloc.dart';
Expand Down

0 comments on commit f3718c7

Please sign in to comment.