Flutter bloc library
Проблема с авторизацией юзера с блоком.
Widget build(BuildContext context) {
return MaterialApp(
home: MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => AuthBloc(authServiceTest: authServiceTest)
..add(AppStartedEvent()),
),
],
child: BlocBuilder<AuthBloc, AuthState>(builder: (context, state) {
if (state is Authenticated) {
return app(state.user);
} else if (state is UnAuthenticated) {
return HomeScreenTest();
} else {
return Container();
}
}),
),
),
);
}
Widget app(FirebaseUser user) {
return Center(
child: Text('hello'),
);
}
}
Блок
class AuthBloc extends Bloc<AuthEvent, AuthState> {
AuthServiceTest authServiceTest;
AuthBloc({@required AuthServiceTest authServiceTest}) {
this.authServiceTest = authServiceTest;
}
@override
AuthState get initialState => AuthInitial();
@override
Stream<AuthState> mapEventToState(AuthEvent event) async* {
if (event is AppStartedEvent) {
try {
var isSignedin = await authServiceTest.isSignedIn();
if (isSignedin) {
var user = await authServiceTest.currentUser();
yield Authenticated(user: user);
} else {
yield UnAuthenticated();
}
} catch (e) {
yield UnAuthenticated();
}
}
}
}
блок ивент
class AppStartedEvent extends AuthEvent {
@override
List<Object> get props => throw UnimplementedError();
}
блок стэйт
class Authenticated extends AuthState {
final FirebaseUser user;
Authenticated({@required this.user});
@override
List<Object> get props => [];
}
class UnAuthenticated extends AuthState {
@override
List<Object> get props => throw UnimplementedError();
все функции
class AuthServiceTest {
FirebaseAuth auth = FirebaseAuth.instance;
Future registerUser(String email, String password) async {
var authResult = await auth.createUserWithEmailAndPassword(
email: email, password: password);
return authResult.user;
}
Future signIn(email, password) async {
var authResult = await auth.signInWithEmailAndPassword(
email: email,
password: password,
);
return authResult.user;
}
Future signOut() async {
await auth.signOut();
}
Future<bool> isSignedIn() async {
var currentUser = await auth.currentUser();
return currentUser != null;
}
Future currentUser() async {
var user = await FirebaseAuth.instance.currentUser();
return user;
}
}
Авторизация работает, после должен показывать виджет app, но не показывает. Либо проблемы в блоке с логикой или функции я прописал не правильно с получением юзера.
Ответы (2 шт):
Писал по памяти возможно где-то нужно поправить. Метод isSignedIn() можно удалить.
Future currentUser() async {
FirebaseUser user = await auth.currentUser();
return user;
}
...
@override
Stream<AuthState> mapEventToState(AuthEvent event) async* {
if (event is AppStartedEvent) {
authServiceTest.isSignedIn().then((user){
if (user.uid != null) {
print("User: ${user.uid}");
yield Authenticated(user: user);
} else {
print("User null");
yield UnAuthenticated();
}
}).catchError((e) {
print("Error: ${e.error}");
yield UnAuthenticated();
});
}
}
Если в консоль ничего не выведет значит проблема в этом if (event is AppStartedEvent).
Как происходит авторизация вашего пользователя? Если при помощи вызова AuthServiceTest.signIn(email, password) то Ваш BloC не может отслеживать эти изменения, вам надо добавить в Bloc два дополнительных события:
SignIn & SignOut которые внутри блока будут вызывать соответсвующие методы из AuthServiceTest
Это будет выглядеть приблизительно так:
события
class AppStartedEvent extends AuthEvent {
@override
List<Object> get props => [];
}
class SignInEvent extends AuthEvent {
SignInEvent(this.email, this.password);
final String email, password;
@override
List<Object> get props => [email, password];
}
class SignOutEvent extends AuthEvent {
@override
List<Object> get props => [];
}
сам блок:
class AuthBloc extends Bloc<AuthEvent, AuthState> {
AuthBloc({@required this.authServiceTest})
final AuthServiceTest authServiceTest;
@override
AuthState get initialState => AuthInitial();
@override
Stream<AuthState> mapEventToState(AuthEvent event) async* {
if (event is AppStartedEvent) {
try {
var isSignedin = await authServiceTest.isSignedIn();
if (isSignedin) {
var user = await authServiceTest.currentUser();
yield Authenticated(user: user);
} else {
yield UnAuthenticated();
}
} catch (e) {
yield UnAuthenticated();
}
}
if (event is SignInEvent) {
try {
final user = await authServiceTest.signIn(event.email, event.password);
yield Authenticated(user: user);
} catch (error) {
yield UnAuthenticated();
}
}
if (event is SignOutEvent) {
authServiceTest.signOut();
yield UnAuthenticated();
}
}
}
После этого вызов authBloc.add(SignInEvent(email, password)) и authBloc.add(SignOutEvent()) будет приводить к соответствующим изменениям в состоянии блока и перерисовке UI, что в итоге при авторизации и отобразит ваш виджет app