Last active
October 1, 2020 10:06
-
-
Save magicleon94/4efb4bcbee6b377cf6d5c2ab4cb5a705 to your computer and use it in GitHub Desktop.
Authentication Bloc: simple structure for having an auth BLoC with different flavors. Firebase flavor implemented for now. Only email/password auth for now.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:bloc/bloc.dart'; | |
import 'package:my_app/features/auth/model/user.dart'; | |
import 'package:meta/meta.dart'; | |
part 'auth_event.dart'; | |
part 'auth_state.dart'; | |
abstract class AuthBloc extends Bloc<AuthEvent, AuthState> { | |
AuthBloc([AuthState initialState]) : super(initialState ?? AuthInitial()); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
part of 'auth_bloc.dart'; | |
enum LoginType { | |
PASSWORD, | |
} | |
@immutable | |
abstract class AuthEvent {} | |
class AuthInit extends AuthEvent {} | |
class AuthLogin extends AuthEvent { | |
final String email; | |
final String password; | |
final LoginType loginType; | |
AuthLogin({ | |
@required this.email, | |
@required this.password, | |
this.loginType = LoginType.PASSWORD, | |
}); | |
} | |
class AuthLogout extends AuthEvent {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
part of 'auth_bloc.dart'; | |
@immutable | |
abstract class AuthState {} | |
class AuthInitial extends AuthState {} | |
class AuthLoggedIn extends AuthState { | |
final User user; | |
AuthLoggedIn(this.user); | |
} | |
class AuthLoggedOut extends AuthState {} | |
class AuthError extends AuthState { | |
final Exception exception; | |
AuthError(this.exception); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'package:my_app/features/auth/bloc/auth_bloc.dart'; | |
import 'package:my_app/features/auth/model/user.dart'; | |
import 'package:firebase_auth/firebase_auth.dart' as firebase; | |
import 'package:firebase_core/firebase_core.dart'; | |
class FirebaseAuthBloc extends AuthBloc { | |
FirebaseAuthBloc() : super(AuthInitial()); | |
firebase.FirebaseAuth auth; | |
Future<void> _init() async { | |
await Firebase.initializeApp(); | |
auth = firebase.FirebaseAuth.instance; | |
} | |
@override | |
Stream<AuthState> mapEventToState( | |
AuthEvent event, | |
) async* { | |
try { | |
switch (event.runtimeType) { | |
case AuthInit: | |
await _init(); | |
if (auth.currentUser != null) { | |
await refreshLogin(); | |
final user = await User.fromFirebaseUser(auth.currentUser); | |
yield AuthLoggedIn(user); | |
} else { | |
yield AuthLoggedOut(); | |
break; | |
} | |
break; | |
case AuthLogin: | |
final userCredential = await login(event); | |
final user = await User.fromFirebaseUser(userCredential.user); | |
yield AuthLoggedIn(user); | |
break; | |
case AuthLogout: | |
await auth.signOut(); | |
yield AuthLoggedOut(); | |
break; | |
default: | |
throw UnimplementedError(); | |
} | |
} on Exception catch (e) { | |
yield AuthError(e); | |
} | |
} | |
Future<firebase.UserCredential> login( | |
AuthLogin event, | |
) async { | |
switch (event.loginType) { | |
case LoginType.PASSWORD: | |
return _loginWithEmailAndPassword(event.email, event.password); | |
break; | |
default: | |
throw UnimplementedError(); | |
} | |
} | |
Future<firebase.UserCredential> _loginWithEmailAndPassword( | |
String email, String password) { | |
return auth.signInWithEmailAndPassword(email: email, password: password); | |
} | |
Future<void> refreshLogin() { | |
return auth.currentUser.reload(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:firebase_auth/firebase_auth.dart' as firebase; | |
import 'package:meta/meta.dart'; | |
class User { | |
final String displayName; | |
final String email; | |
final bool emailVerified; | |
final String photoURL; | |
final String phoneNumber; | |
final bool isAnonymous; | |
final String idToken; | |
final String refreshToken; | |
User({ | |
this.displayName, | |
this.email, | |
this.emailVerified, | |
this.photoURL, | |
this.phoneNumber, | |
this.isAnonymous, | |
@required this.idToken, | |
@required this.refreshToken, | |
}); | |
static Future<User> fromFirebaseUser(firebase.User user) async => User( | |
displayName: user.displayName, | |
email: user.email, | |
emailVerified: user.emailVerified, | |
photoURL: user.photoURL, | |
phoneNumber: user.phoneNumber, | |
isAnonymous: user.isAnonymous, | |
idToken: await user.getIdToken(), | |
refreshToken: user.refreshToken, | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment