Phi*_*ume 8 dart firebase-authentication flutter flutter-bloc flutter-go-router
我使用 go_router 进行导航,使用 flutter_bloc 进行状态管理。
我想使用refreshListenable并在我的GoRouter配置中监听我的AuthBloC事件,但是,我无权访问我的GoRouter中的上下文,并且我不想提供它。
我发现的大多数答案都已过时,或者使用 StreamBuilder 等替代方案在事件更改时重新渲染整个应用程序,这并不理想。
如何在上下文之外监听我的 AuthEvents?
主程序.dart
return RepositoryProvider.value(
value: authRepo,
child: BlocProvider(
create: (_) => AuthBloc(authRepo),
child: MaterialApp.router(
...
routerConfig: Routes.router,
builder: (_, child) {
final isRTL = LocaleSettings.currentLocale == AppLocale.ar;
return Directionality(
textDirection: isRTL ? TextDirection.rtl : TextDirection.ltr,
child: child!,
);
},
),
),
Run Code Online (Sandbox Code Playgroud)
块/auth/auth_bloc.dart
class AuthBloc extends Bloc<AuthEvent, AuthState> {
AuthBloc(this._authenticationRepository) : super(const AuthState()) {
on<AuthEvent>((event, emit) {
event.when(
authStateChangeEvent: (account) => _authStateChangeEvent(account, emit),
signOutEvent: _signOutEvent,
verifyAccount: _verifyAccount,
);
});
_userSubscription = _authenticationRepository.user.listen((account) {
add(AuthEvent.authStateChangeEvent(account));
});
}
late final StreamSubscription<Account> _userSubscription;
final AuthenticationRepository _authenticationRepository;
void _authStateChangeEvent(
Account account,
Emitter<AuthState> emit,
) {
...
}
void _signOutEvent() {
...
}
void _verifyAccount() {
...
}
@override
Future<void> close() {
_userSubscription.cancel();
return super.close();
}
}
Run Code Online (Sandbox Code Playgroud)
路由器.dart
class Routes {
Routes._();
static final _rootNavigatorKey = GlobalKey<NavigatorState>();
static GoRouter get router => _router;
static final GoRouter _router = GoRouter(
navigatorKey: _rootNavigatorKey,
refreshListenable: , // ! Listen to Auth Changes
routes: [..._directNavigations, ..._nestedNavigations],
redirect: _authGuard, //
);
static String? _authGuard(BuildContext context, GoRouterState state) {
final authState = context.watch<AuthBloc>().state;
print(authState.toString());
final isAuthenticated = authState.authStatus == AuthStatus.authenticated;
final isVerified =
authState.account != null && authState.account!.emailVerified;
/// ... Some logic for redirection
return null;
}
...
}
Run Code Online (Sandbox Code Playgroud)
当我使用 context.go/context.push 导航时遇到此错误
"Tried to listen to a value exposed with provider, from outside of the widget tree.\n\nThis is
js_primitives.dart:30 likely caused by an event handler (like a button's onPressed) that called\nProvider.of without
js_primitives.dart:30 passing `listen: false`.\n\nTo fix, write:\nProvider.of<AuthBloc>(context, listen: false);\n\nIt is
js_primitives.dart:30 unsupported because may pointlessly rebuild the widget associated to the\nevent handler, when the
js_primitives.dart:30 widget tree doesn't care about the value.\n\nThe context used was:
js_primitives.dart:30 Navigator-[LabeledGlobalKey<NavigatorState>#31496](dependencies: [HeroControllerScope,
js_primitives.dart:30 UnmanagedRestorationScope, _FocusTraversalGroupMarker], state: NavigatorState#795d6(tickers:
js_primitives.dart:30 tracking 1 ticker))\n"
Run Code Online (Sandbox Code Playgroud)
完整的崩溃日志: https: //pastebin.com/3A3pdKtr
注意:我愿意用更改通知程序替换我的 Auth BloC,但我不确定这是否是处理此问题的正确方法。
| 归档时间: |
|
| 查看次数: |
2095 次 |
| 最近记录: |