The app is giving the following error: " (pageBuilder != null) ^ (builder != null) One of builder or pageBuilder must be provided, but not both" when running.
This is my main function
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final sharedPreferences = await SharedPreferences.getInstance();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// import flutter_web_plugings/url_strategy.dart
// usePathUrlStrategy();
runApp(const ProviderScope(child: MyApp()));
// runApp(SidebarXExampleApp());
}
here is the Root widget :
class MyApp extends ConsumerWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context, WidgetRef ref) {
final goRouter = ref.watch(goRouterProvider);
return MaterialApp.router(
routerConfig: goRouter,
title: 'ARPTC',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
// routerDelegate: ref.watch(goRouterProvider).routerDelegate,
// routeInformationParser: ref.watch(goRouterProvider).routeInformationParser,
// home: const AuthCheckerScreen(),
);
}
}
And here is the provider for goRouter (I have commented the redirect logic for the time being to simplify the app and make it run first) :
final goRouterProvider = Provider<GoRouter>((ref) {
final rootNavigatorKey = GlobalKey<NavigatorState>();
final _shellNavigatorAKey = GlobalKey<NavigatorState>(debugLabel: 'shellA');
final _shellNavigatorBKey = GlobalKey<NavigatorState>(debugLabel: 'shellB');
return GoRouter(
initialLocation: '/dashboard',
navigatorKey: rootNavigatorKey,
debugLogDiagnostics: true,
routes: [
StatefulShellRoute.indexedStack(
branches: [
StatefulShellBranch(
navigatorKey: _shellNavigatorAKey,
routes: [
GoRoute(
path: '/a',
pageBuilder: (context, state) => const NoTransitionPage(
child: RootScreen(label: 'A', detailsPath: '/a/details'),
),
routes: [
GoRoute(
path: 'details',
builder: (context, state) => const DetailsScreen(label: 'A'),
),
],
),
],
),
StatefulShellBranch(
navigatorKey: _shellNavigatorBKey,
routes: [
// Shopping Cart
GoRoute(
path: '/b',
pageBuilder: (context, state) => const NoTransitionPage(
child: RootScreen(label: 'B', detailsPath: '/b/details'),
),
routes: [
GoRoute(
path: 'details',
builder: (context, state) => const DetailsScreen(label: 'B'),
),
],
),
],
),
],
)
],
redirect: (context, state) {
// final _authState = ref.watch(authStateProvider);
// return _authState.when(
// data: (data) {
// print("DATA ==> $data");
// User? user = data;
//
// if (user == null){
// debugPrint(":: RETURNING DASHBOARD");
// return '/login';
// }
// // debugPrint(":: RETURNING LOGIN");
// // return '/login';
// },
// loading: () => '/login',
// error: (e, trace) => '/error');
},
);
}
);
But when I use simple the following GoRouter without StatefullShellRoute it works :
final goRouterProviderTwo = Provider<GoRouter>((ref){
return router(ref);
});
GoRouter router(ProviderRef ref) {
final rootNavigatorKey = GlobalKey<NavigatorState>();
final shellNavigatorCourrierKey =
GlobalKey<NavigatorState>(debugLabel: 'shellCourrier');
final shellNavigatorDashboardKey =
GlobalKey<NavigatorState>(debugLabel: 'shellDashboard');
final shellNavigatorErrorKey =
GlobalKey<NavigatorState>(debugLabel: 'shellError');
final shellNavigatorLoginKey =
GlobalKey<NavigatorState>(debugLabel: 'shellLogin');
return GoRouter(
initialLocation: '/courriers',
navigatorKey: rootNavigatorKey,
debugLogDiagnostics: true,
routes: [
GoRoute(
path: '/login',
pageBuilder: (context, state) => const NoTransitionPage(
child: LoginScreen(),
),
),
GoRoute(
path: '/dashboard',
pageBuilder: (context, state) => const NoTransitionPage(
child: DashboardPage(),
),
),
GoRoute(
path: '/courriers',
pageBuilder: (context, state) => const NoTransitionPage(
child: ListCourriersScreen(),
),
// routes: [
// GoRoute(
// path: 'details/:courrierId',
// pageBuilder: (context, state) {
//
// return NoTransitionPage(
// child: DetailsCourrierScreen(state.pathParameters['courrierId'] as String));
// },
// ),
// ],
),
GoRoute(
path: '/courriers/:courrierId',
pageBuilder: (context, state) {
return NoTransitionPage(
child: DetailsCourrierScreen(state.pathParameters['courrierId'] as String));
},
),
GoRoute(
path: '/error',
pageBuilder: (context, state) => const NoTransitionPage(
child: Center(
child: Text('Error'),
),
),
)
],
redirect: (context, state) async {
final _authState = ref.watch(authStateProvider);
return _authState.when(
data: (data) {
User? user = data;
// if (user == null && state.location == '/'){
if (user == null ){
debugPrint(":: GO TO LOGIN SCREEN");
return '/login';
}
// debugPrint(":: RETURNING LOGIN");
// return '/login';
},
loading: () => '/login',
error: (e, trace) => '/error');
},
);
}
Any idea why the GoRouter with StatefullShellRoute not working with riverpod ?
The assert uses a XOR to validate pageBuilder or builder (only one can be passed, both or none fails the assert) and it seems you're not providing any: