My app uses Bloc as it's state management. When the app receive state OAuthSignedIn()
, the _navigator
in
WidgetsBinding.instance.addPostFrameCallback((_) {
log('Here');
_navigator.pushAndRemoveUntil(
HomePage.route,
(route) => true,
);
});
Gives error 'newRoute._navigator == null': is not true.
Full code:
class App extends StatelessWidget {
App({super.key});
final SupabaseClient supabaseClient = Supabase.instance.client;
@override
Widget build(BuildContext context) {
return BlocProvider<AppBloc>(
create: (context) => AppBloc(supabaseClient: supabaseClient),
child: const AppView(),
);
}
}
class AppView extends StatefulWidget {
const AppView({super.key});
@override
State<AppView> createState() => _AppViewState();
}
class _AppViewState extends State<AppView> {
final _navigatorKey = GlobalKey<NavigatorState>();
NavigatorState get _navigator => _navigatorKey.currentState!;
StreamSubscription<AuthState>? _authSubscription;
@override
void initState() {
handleOAuthListener();
super.initState();
}
void handleOAuthListener() {
SupabaseClient supabase = Supabase.instance.client;
_authSubscription =
supabase.auth.onAuthStateChange.listen((AuthState data) {
log("handleOAuthListener ${data.event.name}");
handleOAuthSignIn(data);
});
}
void handleOAuthSignIn(AuthState data) {
final event = data.event;
switch (event) {
case AuthChangeEvent.initialSession:
log("Getting initial user");
context.read<AppBloc>().add(GetInitialUser());
case AuthChangeEvent.signedIn:
log("OAuth Sign in success");
context.read<AppBloc>().add(OAuthSignInSuccessfullEvent());
case AuthChangeEvent.tokenRefreshed:
log("OAuth token refreshed");
context.read<AppBloc>().add(OAuthSignInSuccessfullEvent());
default:
break;
}
}
@override
void dispose() {
_authSubscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _navigatorKey,
title: 'MyApp',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
builder: (context, child) {
return BlocListener<AppBloc, AppState>(
listenWhen: (previous, current) => current != previous,
listener: (context, state) {
switch (state) {
case OAuthSignedIn():
WidgetsBinding.instance.addPostFrameCallback((_) {
log('Here');
_navigator.pushAndRemoveUntil(
HomePage.route,
(route) => true,
);
});
break;
case OAuthSignedOut():
WidgetsBinding.instance.addPostFrameCallback((_) {
log('Signed out here');
_navigator.pushAndRemoveUntil(
LoginPage.route,
(route) => true,
);
});
break;
default:
break;
}
},
child: child,
);
},
onGenerateRoute: (_) => SplashPage.route,
);
}
}
I did tried changing the WidgetsBinding
to ScheduleBinding
and using Future.delayed
(with various durations) instead of both bindings, but it doesn't seem to solve the issue
Also, using Future.delayed
changed the error to '!_debugLocked': is not true.