Skip to content

Instantly share code, notes, and snippets.

@arnaudelub
Created March 23, 2021 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arnaudelub/562982601fd7be6aa6866a10137577f2 to your computer and use it in GitHub Desktop.
Save arnaudelub/562982601fd7be6aa6866a10137577f2 to your computer and use it in GitHub Desktop.
final auth_facade
class FirebaseAuthFacade implements IAuthFacade {
final auth.FirebaseAuth _firebaseAuth;
final GoogleSignIn _googleSignIn;
final FacebookLogin _facebookLogin;
FirebaseAuthFacade(this._firebaseAuth, this._facebookLogin,
this._googleSignIn);
@override
Stream<auth.User> userState() async* {
yield* _firebaseAuth.authStateChanges();
}
@override
Future<auth.User> getCurrentUser() async {
return _firebaseAuth.currentUser;
}
@override
Future<void> sendVerificationEmail() aync {
final auth.User user = getCurrentUser();
if(!user.emailVerified){
await user.sendEmailVerification();
}
}
@override
Future<Either<AuthFailure, Unit>> signInAsAnonym() async {
try {
await _firebaseAuth.signInAnonymously();
return const Right(unit);
} on auth.FirebaseAuthException catch (e) {
return const Left(AuthFailure.operationNotAllowed());
}
}
@override
Future<Either<AuthFailure, Unit>> registerWithEmailAndPassword({
required EmailAddress email,
required Password password,
bool isLinkWithCredentials = false,
}) async {
final emailAddressStr = email.getOrCrash();
final passwordStr = password.getOrCrash();
auth.User previousUser;
try {
if (isLinkWithCredentials) {
// This is where the magic happens
// First get the currentUSer
previousUser = await getCurrentUser();
// Get the credentials from the EmailAuthProvider
final authCreds = auth.EmailAuthProvider.credential(
email: emailAddressStr, password: passwordStr);
// And link it to the current account
await previousUser.linkWithCredential(authCreds);
} else {
final auth.UserCredential userCreds =
await _firebaseAuth.createUserWithEmailAndPassword(
email: emailAddressStr,
password: passwordStr,
);
}
return const Right(unit);
} on auth.FirebaseAuthException catch (e) {
if (e.code == 'email-already-in-use') {
return const Left(AuthFailure.emailAlreadyInUse());
} else if (e.code == 'invalid-email') {
return const Left(AuthFailure.invalidEmail());
} if (e.code == 'operation-not-allowed') {
return const Left(AuthFailure.operationNotAllowed());
} if (e.code == 'week-password') {
return const Left(AuthFailure.weekPassword());
} else {
return const Left(AuthFailure.serverError());
}
}
}
@override
Future<void> resetPassword({@required EmailAddress email}) =>
_firebaseAuth.sendPasswordResetEmail(email: email.getOrCrash());
@override
Future<Either<AuthFailure, Unit>> signInWithEmailAndPassword({
@required EmailAddress email,
@required Password password,
bool reauth = false,
}) async {
final emailAddressStr = email.getOrCrash();
final passwordStr = password.getOrCrash();
try {
final auth.UserCredential userCreds =
await _firebaseAuth.signInWithEmailAndPassword(
email: emailAddressStr,
password: passwordStr,
);
return const Right(unit);
} on auth.FirebaseAuthException catch (e) {
if (e.code == 'user-not-found' || e.code == 'wrong-password') {
return const Left(AuthFailure.invalidEmailAndPasswordCombination());
} else {
return const Left(AuthFailure.serverError());
}
}
}
@override
Future<Either<AuthFailure, Unit>> signInWithGoogle(
{bool reauth = false}) async {
try {
auth.User previousUser;
final googleUser = await _googleSignIn.signIn();
if (googleUser == null) {
return const Left(AuthFailure.cancelledByUser());
}
final googleAuthentication = await googleUser.authentication;
if (reauth) {
previousUser = await getCurrentUser();
final relinkCred = auth.GoogleAuthProvider.credential(
idToken: googleAuthentication.idToken,
accessToken: googleAuthentication.accessToken);
await previousUser.linkWithCredential(relinkCred);
} else {
final authCredential = auth.GoogleAuthProvider.credential(
idToken: googleAuthentication.idToken,
accessToken: googleAuthentication.accessToken);
final auth.UserCredential userCreds =
await _firebaseAuth.signInWithCredential(authCredential);
}
return right(unit);
} on auth.FirebaseAuthException catch (e) {
if (e.code == 'email-already-in-use') {
return const Left(AuthFailure.emailAlreadyInUse());
} else if (e.code == 'invalid-email') {
return const Left(AuthFailure.invalidEmail());
} if (e.code == 'operation-not-allowed') {
return const Left(AuthFailure.operationNotAllowed());
} if (e.code == 'user-disabled') {
return const Left(AuthFailure.userDisabled());
} else {
return const Left(AuthFailure.serverError());
}
}
}
@override
Future<Either<AuthFailure, Unit>> signInWithApple(
{bool reauth = false}) async {
try {
auth.User previousUser;
if (reauth) {
previousUser = await getCurrentUser();
}
final credential = await apple.SignInWithApple.getAppleIDCredential(
scopes: [
apple.AppleIDAuthorizationScopes.email,
apple.AppleIDAuthorizationScopes.fullName,
],
webAuthenticationOptions: apple.WebAuthenticationOptions(
clientId: appleClientId,
redirectUri: Uri.parse(appleRedirectUri),
),
);
if (credential == null) {
printDev("Cancelled by user");
return const Left(AuthFailure.cancelledByUser());
}
// basically appleProvider is the String "apple.com"
final oAuthProvider = auth.OAuthProvider(appleProvider);
final newCredentials = oAuthProvider.credential(
idToken: credential.identityToken,
accessToken: credential.authorizationCode,
);
if (reauth) {
await previousUser.linkWithCredential(newCredentials);
} else {
final auth.UserCredential userCreds =
await _firebaseAuth.signInWithCredential(newCredentials);
}
return right(unit);
} on apple.SignInWithAppleException catch (e) {
if (e is apple.SignInWithAppleNotSupportedException) {
return const Left(AuthFailure.wrongIosVersion());
}
return const Left(AuthFailure.serverError());
} on auth.FirebaseAuthException catch (e) {
if (e.code == 'email-already-in-use') {
return const Left(AuthFailure.emailAlreadyInUse());
} else if (e.code == 'invalid-email') {
return const Left(AuthFailure.invalidEmail());
} if (e.code == 'operation-not-allowed') {
return const Left(AuthFailure.operationNotAllowed());
} if (e.code == 'user-disabled') {
return const Left(AuthFailure.userDisabled());
} else {
return const Left(AuthFailure.serverError());
}
}
}
@override
Future<Either<FirebaseauthFailure, Unit>> changePassword(
Password newPassword, Password oldPassword, EmailAddress email) async {
final auth.User user = await getCurrentUser();
try {
await user.updatePassword(newPassword.getOrCrash());
return right(unit);
} on auth.FirebaseAuthException catch (e) {
printDev("error changing password $e");
if (e.code.contains('requires-recent-login')) {
try {
final auth.AuthCredential credential =
auth.EmailAuthProvider.credential(
email: email.getOrCrash(),
password: oldPassword.getOrCrash());
await user.reauthenticateWithCredential(credential);
return right(unit);
} on auth.FirebaseAuthException catch (e) {
if (e.code.contains('user-mismatch')) {
return left(const FirebaseauthFailure.userMismatch());
} else if (e.code.contains('user-not-found')) {
return left(const FirebaseauthFailure.userNotFound());
} else if (e.code.contains('invalid-credential')) {
return left(const FirebaseauthFailure.invalidCredential());
} else if (e.code.contains('invalid-email')) {
return left(const FirebaseauthFailure.invalidEmail());
} else if (e.code.contains('wrong-password')) {
return left(const FirebaseauthFailure.wrongPassword());
}
}
} else if (e.code.contains('weak-password')) {
return left(const FirebaseauthFailure.weakPassword());
}
return left(const FirebaseauthFailure.serverError());
}
}
@override
Future<void> resetPassword({required EmailAddress email}) =>
_firebaseAuth.sendPasswordResetEmail(email: email.getOrCrash());
@override
Future<Either<FirebaseauthFailure, Unit>> changePassword(
Password newPassword, Password oldPassword, EmailAddress email) async {
final auth.User user = await getCurrentUser();
try {
await user.updatePassword(newPassword.getOrCrash());
return right(unit);
} on auth.FirebaseAuthException catch (e) {
printDev("error changing password $e");
if (e.code.contains('requires-recent-login')) {
try {
final auth.AuthCredential credential =
auth.EmailAuthProvider.credential(
email: email.getOrCrash(),
password: oldPassword.getOrCrash());
await user.reauthenticateWithCredential(credential);
return right(unit);
} on auth.FirebaseAuthException catch (e) {
if (e.code.contains('user-mismatch')) {
return left(const FirebaseauthFailure.userMismatch());
} else if (e.code.contains('user-not-found')) {
return left(const FirebaseauthFailure.userNotFound());
} else if (e.code.contains('invalid-credential')) {
return left(const FirebaseauthFailure.invalidCredential());
} else if (e.code.contains('invalid-email')) {
return left(const FirebaseauthFailure.invalidEmail());
} else if (e.code.contains('wrong-password')) {
return left(const FirebaseauthFailure.wrongPassword());
}
}
} else if (e.code.contains('weak-password')) {
return left(const FirebaseauthFailure.weakPassword());
}
return left(const FirebaseauthFailure.serverError());
}
}
@override
Future<void> signedOut() => _firebaseAuth.signOut();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment