I combined Firebase auth, riverpod, and Gorouter via Luca Venir's repository here. It really works great. Now my issue is that I'm making a web app, and I don't know how to access the GoRouter routes that are inside the routerProvider to change the page when the user clicks on a nav item. It seems like a simple issue, but I've had problems with navigation and global keys before.
I've abbreviated my code to what I believe are the most essential parts, but let me know if more is needed. My routerProvider is based on my auth repo, which utilizes Firebase.
`final routerProvider = Provider<GoRouter>((ref) {
final authState = ref.watch(authStateProvider);
return GoRouter(
navigatorKey: key,
debugLogDiagnostics: true,
initialLocation: SplashPage.routeLocation,
routes: [
GoRoute(
path: SplashPage.routeLocation,
name: SplashPage.routeName,
builder: (context, state) {
return const SplashPage();
},
),
GoRoute(
path: '/preloginhome',
name: 'preloginhome',
builder: (context, state) {
return const PreLoginHome();
},
),
GoRoute(
path: '/dashboard',
name: 'dashboard',
builder: (context, state) {
return const Dashboard();
},
),
//more code
The main app watches the above routerProvider `
class MyAppWithFirebase extends ConsumerWidget {
const MyAppWithFirebase({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final router = ref.watch(routerProvider);
return MaterialApp.router(
theme: CustomTheme.darkTheme,
routeInformationParser: router.routeInformationParser,
routerDelegate: router.routerDelegate,
routeInformationProvider: router.routeInformationProvider,
);
}
}
Now my questoion is, how can I navigate with the routes declared in routerProvider? My custom app bar is something like this but I'm missing something..
class CustomAppBar extends ConsumerWidget implements PreferredSizeWidget {
const CustomAppBar({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final router = ref.watch(routerProvider);
final isUserSignedIn = FirebaseAuth.instance.currentUser != null;
return AppBar(
title: TextButton(
onPressed: isUserSignedIn
? () {
key.currentState!.pushNamed(Dashboard.routeLocation);
}
: () {
key.currentState!.pushNamed('/preloginhome');
},
child: Text(
'Agroopet',
style: TextStyle(
fontSize: 22,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
Just don't know how to properly access the routes in the routerProvider and also am incorrectly setting the global nav key.
With the above code I get the error
"Another exception was thrown: Navigator.onGenerateRoute was null, but the route named "/preloginhome" was referenced."
This question wasn't even framed in the right way. I've made some progress now when I'm able to navigate when I'm logged in (I was testing while not authenticated) by calling the routerProvider like so:
onPressed: isUserSignedIn
? () => ref.read(routerProvider).go(Dashboard.routeLocation)
: () {
ref.read(routerProvider).go(PreLoginHome.routeLocation);
},
Now it seems like the issue is in my own AuthChecker class because I can't go anywhere besides the login screen when the user isn't authenticated.
class AuthChecker extends ConsumerWidget {
const AuthChecker({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final authState = ref.watch(authStateProvider);
return authState.when(
data: (user) {
if (user != null) return const Dashboard();
return const LoginPage();
},
loading: () => const LoadingScreen(),
error: (e, trace) => ErrorScreen(e, trace));
}
}