csells / go_router

The purpose of the go_router for Flutter is to use declarative routes to reduce complexity, regardless of the platform you're targeting (mobile, web, desktop), handling deep linking from Android, iOS and the web while still allowing an easy-to-use developer experience.
https://gorouter.dev
442 stars 96 forks source link

Navigational Observers #46

Closed shriharip closed 2 years ago

shriharip commented 2 years ago

Hello,

Thanks for all the effort here. I have a question related to using of navigational observers. How can we use them with go_router? For example third party apps like FirebaseAnalyticsObserver that need to be passed to this router.

Best, Hari

csells commented 2 years ago

I added support in v1.1.0. Give it a try and let me know if it's working.

shriharip commented 2 years ago

Thanks Chris, that was super quick. I have added it. Somehow the Firebase tracking is not happening. But I think it is a different issue. I will keep you posted on this. Regards Hari

rkunboxed commented 2 years ago

Hi Chris, thanks for this excellent package!

Rather than open up a new issue I thought I'd pop my question over here as I'm having issues implementing an observer for analytics. Here is my router (a wee bit simplified):

GoRouter(
      urlPathStrategy: UrlPathStrategy.path,
      routes: [
        GoRoute(
          path: '/',
          name: 'home',
          pageBuilder: (context, state) => CustomTransitionPage<void>(
            key: state.pageKey,
            child: const HomePage(),
            transitionsBuilder: (context, animation, secondaryAnimation, child) => child,
          ),
        ),
        GoRoute(
          path: '/login',
          name: 'login',
          pageBuilder: (context, state) => CustomTransitionPage<void>(
            key: state.pageKey,
            child: const LoginPage(),
            transitionsBuilder: (context, animation, secondaryAnimation, child) => child,
          ),
        ),
      ],
      errorPageBuilder: (BuildContext context, GoRouterState state) {
        return MaterialPage<Widget>(
          key: state.pageKey,
          child: PageNotFound(state.location),
        );
      },
      observers: [
        GoRouterObserver(analytics: analytics)
      ],
    );

And here is my observer.

class GoRouterObserver extends NavigatorObserver {
  GoRouterObserver({required this.analytics});
  final FirebaseAnalytics analytics;

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    analytics.setCurrentScreen(screenName: route.settings.name);
    print('PUSHED SCREEN: ${route.settings.name}'); //name comes back null
  }
}

My print statement is firing so didPush is being called but route.settings.name is coming back null. I've specified a name for every route. Is there something else I am missing? I am using top-level redirection in case that might play a role in this. Thanks!

csells commented 2 years ago

Correct. The route.settings.name value is set when you call methods on the Navigator, e.g. pushNamed. Those aren't set by GoRouter. Can I ask what problem you're trying to solve?

rkunboxed commented 2 years ago

I'm just trying to report the page view to analytics.

csells commented 2 years ago

You can always access the GoRouter instance and use the location property to get to the current location in your app for logging.

csells commented 2 years ago

Hey, @rkunboxed. v2.5.2 adds some add'l data to the NavigatorObserver by default if you're using the new builder methods in your routes as described here: https://gorouter.dev/migrating-to-25