abhi jain
abhi jain

Reputation: 57

Flutter go_router throws error unknown route name: /auth/:uid with '_nameToPath.containsKey(name)'

In my flutter app I am building routes with go_router and flutter_riverpod but as I have setup my routes with provider I started getting this error

The following assertion was thrown building
DefaultSelectionStyle:
unknown route name: /auth/:uid
'package:go_router/src/configuration.dart':
Failed assertion: line 243 pos 12:
'_nameToPath.containsKey(name)'

Here is my main.dart file where I am calling routes.


void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
      .then((_) async {
    await Firebase.initializeApp();
    await FirebaseAppCheck.instance
        .activate(androidProvider: AndroidProvider.playIntegrity);

    runApp(
      const ProviderScope(
        child: MyApp(),
      ),
    );
  });
  FlutterError.demangleStackTrace = (StackTrace stack) {
    if (stack is stack_trace.Trace) return stack.vmTrace;
    if (stack is stack_trace.Chain) return stack.toTrace().vmTrace;
    return stack;
  };
}

class MyApp extends ConsumerWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp.router(
      debugShowCheckedModeBanner: false,
      title: 'DiscountLo',
      theme: AppTheme.theme,
      locale: ref.watch(languageNotifierProvider),
      localizationsDelegates: {
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate
      },
      supportedLocales: [Locale("en"), Locale("hi")],
      routerDelegate:  ref.watch(routeProvider).routerDelegate,
      routeInformationParser:  ref.watch(routeProvider).routeInformationParser,
      routeInformationProvider:  ref.watch(routeProvider).routeInformationProvider,
    );
  }
}

my router.dart file where I have created a provider and I am trying to call redirect to handle state management and protect routes.

final routeProvider = Provider<GoRouter>(
  (ref) {
    return GoRouter(
      routes: [
        GoRoute(
          name: "home",
          path: RouteNameConstants.home,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: const HomeView(),
          ),
        ),
        GoRoute(
          name: "splash",
          path: RouteNameConstants.splash,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: const SplashScreen(),
          ),
        ),
        GoRoute(
          name: "onboard",
          path: RouteNameConstants.onboarding,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: const OnboardingView(),
          ),
        ),
        GoRoute(
          name: "error",
          path: RouteNameConstants.error,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: ErrorPage(text: state.pathParameters['text']!),
          ),
        ),
        GoRoute(
          name: "auth",
          path: RouteNameConstants.authState,
          pageBuilder: (BuildContext context, GoRouterState state) {
            return MaterialPage(
              child: AuthChanges(uid: state.pathParameters['uid']!),
            );
          },
        ),
        GoRoute(
          name: "filter",
          path: RouteNameConstants.filter,
          pageBuilder: (BuildContext context, GoRouterState state) {
            return MaterialPage(
              child: FilterView(
                index: double.tryParse(state.pathParameters['index']!)!.toInt(),
                category: state.pathParameters['category']!,
              ),
            );
          },
        ),
      ],
      redirect: (context, state) {
        final loginState = ref.watch(authStateChangeProvider);
        if (loginState.isLoading) {
          return RouteNameConstants.splash;
        } else if (loginState.hasError) {
          return state.namedLocation(
            RouteNameConstants.error,
            pathParameters: {
              "text": loginState.error.toString(),
            },
          );
        } else if (loginState.value != null) {
          return state.namedLocation(RouteNameConstants.authState,
              pathParameters: {"uid": loginState.value!.uid});
        } else {
          return RouteNameConstants.onboarding;
        }
      },
    );
  },
);

my routers path name constants

class RouteNameConstants {
  static const String home = '/';
  static const String splash = '/splash';
  static const String onboarding = '/onboarding';
  static const String authState = '/auth/:uid';
  static const String error = '/error/:text';
  static const String filter = '/filter';
}

please if anyone can help me

Upvotes: 1

Views: 3628

Answers (2)

Abdelrahman Tareq
Abdelrahman Tareq

Reputation: 2317

You need to add name property to the route like this:

static const kMainHomeView = '/home';
static const kWelcomeView = '/welcome';

GoRoute(
        path: kWelcomeView,
        name: kWelcomeView,
        builder: (context, state) {
          return const WelcomeView();
        },
      ),


GoRoute(
        path: kMainHomeView,
        name: kMainHomeView,
        builder: (context, state) {
          return const MainHomeView();
        },
      ),

Upvotes: 0

abhi jain
abhi jain

Reputation: 57

I was using

class RouteNameConstants {
  static const String home = 'home';
  static const String splash = 'splash';
  static const String onboarding = 'onboard';
  static const String authState = 'auth';
  static const String error = 'error';
  static const String filter = 'filter';
  static const String profile = 'profile';
  static const String phone = 'phone';
  static const String otp = 'otp';
  static const String profilecontent = 'profilecontent';
}

as path in GoRoute instead now I use as name and defined path this way solves my problem

import 'package:discountlo/core/route_constant.dart';
import 'package:discountlo/features/auth/views/otp_view.dart';
import 'package:discountlo/features/auth/views/phone_view.dart';
import 'package:discountlo/features/home/view/filter_view.dart';
import 'package:discountlo/features/home/view/profile_content_view.dart';
import 'package:discountlo/features/home/view/profile_view.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:discountlo/features/auth/views/onboarding_screen.dart';
import 'package:discountlo/features/auth/views/splash_view.dart';
import 'package:discountlo/features/home/view/home_view.dart';
import 'auth_changes.dart';
import 'error_page.dart';
import 'package:flutter/material.dart';
import 'features/auth/controller/auth_controller.dart';

final _key = GlobalKey<NavigatorState>();

final routeProvider = Provider<GoRouter>(
  (ref) {
    return GoRouter(
      navigatorKey: _key,
      debugLogDiagnostics: true,
      routes: [
        GoRoute(
          name: RouteNameConstants.home,
          path: "/",
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: const HomeView(),
          ),
        ),
        GoRoute(
          path: "/splash",
          name: RouteNameConstants.splash,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: const SplashScreen(),
          ),
        ),
        GoRoute(
          path: "/otp",
          name: RouteNameConstants.otp,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: OTPView(
              phoneNumber: state.pathParameters['phoneNumber']!,
            ),
          ),
        ),
        GoRoute(
          path: "/phone",
          name: RouteNameConstants.phone,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: const PhoneView(),
          ),
        ),
        GoRoute(
          path: "/profile",
          name: RouteNameConstants.profile,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: const ProfileView(),
          ),
        ),
        GoRoute(
          path: "/profilecontent",
          name: RouteNameConstants.profilecontent,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: ProfileContentView(
              clicked: state.pathParameters['clicked']!,
            ),
          ),
        ),
        GoRoute(
          path: "/onboard",
          name: RouteNameConstants.onboarding,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: const OnboardingView(),
          ),
        ),
        GoRoute(
          path: "/error/:text",
          name: RouteNameConstants.error,
          pageBuilder: (BuildContext context, GoRouterState state) =>
              MaterialPage(
            child: ErrorPage(text: state.pathParameters['text']!),
          ),
        ),
        GoRoute(
          path: "/auth/:uid",
          name: RouteNameConstants.authState,
          pageBuilder: (BuildContext context, GoRouterState state) {
            return MaterialPage(
              child: AuthChanges(uid: state.pathParameters['uid']!),
            );
          },
        ),
        GoRoute(
          path: "/filter/:index/:category",
          name: RouteNameConstants.filter,
          pageBuilder: (BuildContext context, GoRouterState state) {
            debugPrint("sdvf ${state.pathParameters}");
            return MaterialPage(
              child: FilterView(
                index: double.tryParse(state.pathParameters['index']!)!.toInt(),
                category: state.pathParameters['category']!,
              ),
            );
          },
        ),
      ],
      redirect: (context, state) {
        final loginState = ref.watch(authStateChangeProvider);
        if (loginState.isLoading) {
          return state.namedLocation(RouteNameConstants.splash);
        } else if (loginState.hasError) {
          return state.namedLocation(
            RouteNameConstants.error,
            pathParameters: {
              "text": loginState.error.toString(),
            },
          );
        } else if (loginState.value != null) {
          return state.namedLocation(RouteNameConstants.authState,
              pathParameters: {"uid": loginState.value!.uid});
        } else {
          return state.namedLocation(RouteNameConstants.onboarding);
        }
      },
    );
  },
);

Upvotes: 0

Related Questions