Giter Site home page Giter Site logo

go_router_riverpod's Introduction

๐Ÿ‘‹ Hi, Iโ€™m @lucavenir ๐Ÿ‘‹

๐Ÿ‘€ I'm a Software Engineer, I live in Udine, Italy, and I'm currently...

  • ๐Ÿ›๏ธ Deepening my Software Engineering skills
  • ๐Ÿฆ Working on Cross Platform Client-side Software w/ Dart
  • ๐Ÿซ‚ Building a team that works with happily, together
  • ๐Ÿฆโ€๐Ÿ”ฅ Learning Phoenix so that I can write fast and fun server-side code

๐ŸŒฑ Iโ€™m currently learning...

  • ๐ŸŽฏ Dart
  • ๐Ÿ’จ Go
  • โš—๏ธ Elixir

I'm focused on...

  • ๐Ÿ‘จโ€๐Ÿ”ฌ Code Quality, Testing, Sw Architecture
  • ๐Ÿ’ž๏ธ Showing love to Open Source Projects
  • ๐Ÿ“ˆ Creating a Product that people can love

Most of my commits are on Gitlab, check my personal GitLab profile at gitlab.com/luca.venir and my corporate profile at gitlab.com/lucavenir.

go_router_riverpod's People

Contributors

abduraimbek avatar gengiscb avatar lucavenir avatar packruble avatar ponnamkarthik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go_router_riverpod's Issues

Add more pages to the examples

This should help understanding navigation a little better.

  • Add a listview in the home page / user page / admin page / guest page
  • Add DetailsRoute with a simple mocked API request
  • Cache the values for 2 minutes
  • Let users hop back and forth these details page and see the caching strategy integrated with go router in action

Go router no longer provide location in GoRouterState after 9.0

I was using state.location in redirect and found compile error after upgrade go router.

From https://pub.dev/packages/go_router/changelog

BREAKING CHANGE:

  • Removes GoRouter.location. Use GoRouterState.of().location instead.
  • GoRouter does not extends ChangeNotifier.
  • Migration guide

I tried updating the code with GoRouterState.of(context).matchedLocation but end up getting There is no modal route above current context like flutter/flutter#130213

Store Firebase User Globally using StateProvider

Excellent example! I'm a newbie in Riverpod. Anyone has any idea how to store the user gotten from firebase after authentication such that I can access the user (including user firebase id) within my app? Thanks

Extend to include support for Firebase dynamic links

I'm trying to extend your example to support firebase dynamic links, both on the Web as well as in Android. However, I'm struggling to get it working in conjunction with authentication. I tried to implement it as shown in this tutorial which also uses go_router + riverpod to get dynamic links working, but I have only been able to get it working on Android.

On the web - as soon as I implement the providers as shown in your example, whenver I load a link fresh it makes a cold start of the application and ends up redirecting me to my main page (after I briefly see the correct location). Any hints on that?

Add tests

  • Make sure I've written some testable code
  • Actually write good tests

Use GoRouter.refreshListenable

GoRouter can get a listenable and refreshes if the listenable notifies the router. In your code you are not using it, but I think it would be the better way to do it. You are listening to the current auth state and rebuild the whole router on a change. The state remains intact because of the global key, but this is probably more expensive than creating a listenable and let GoRouter refresh itself.

example of code_gen + FirebaseAuth + UserRole

Would you be so kind to rework the Firebase Auth example to use generation of GoRouter routes, generation of routerProvider and support for UserRoles ?

Very interesting would be to have as similar solution as possible for the dummy auth example and the one using Firebase Auth.
For example to move await FirebaseAuth.instance.signInAnonymously(); into StreamProvider authProvider.

Question about implementing of `ref.listenSelf` in auth.dart

Hello,

I have a dumb question and apologize in advance if this isn't the correct place to ask it.

In auth.dart, the asynchronous build() calls _persistenceRefreshLogic() which then calls ref.listenSelf(). According to the Riverpod docs, ref.listen() shouldn't be called asynchronously.

Does that guidance not specifically apply to ref.listenSelf() or this usage in general (i.e. if I wanted to call ref.listen in a similar method would it be okay)?

Auto Login dsnt work

auto login dsnt work with external api call

I been test codegen,complete and legacy, their work in test using sharedprefs. however when using external api call
the token stored is always null and this been happen in 3 project with different example

Login not working when using flutter_web_auth

When I try to add the flutter_web_auth dependency to the login method, then no login is happening on the web platform.
It seems like the build method AuthNotifier is triggered again (because of the new opened and then closing tab) and the bulid method of RouterNotifier is not triggered.
Tried to set keepAlive: true but it did not help.

When you hot restart the app, then you are logged in.

Running following code for the web platform fails:

Example code:

  /// Mock of a successful login attempt, which results come from the network.
  Future<void> login(String email, String password) async {
    state = await AsyncValue.guard<User>(() async {
      String webCallbackUrlScheme =
          'http://localhost:5000/auth.html';
      String callbackUrlScheme = 'de.demo.auth';
      await FlutterWebAuth2.authenticate(url: webCallbackUrlScheme, callbackUrlScheme: callbackUrlScheme);

      return Future.delayed(
        networkRoundTripTime,
        () => _dummyUser,
      );
    });
  }

Cleanup and Enhancements

I'm planning to clean up this repository again and hopefully one last time.

  • Delete current legacy folder
  • Delete the current complete_example folder
  • Rename code_gen to example if possible

Show splash screen during Firebase.initializeApp()

First of all, thank you for this great project - the examples are very, very usefull!!! Great work!!

For a personal project i am using riverpod + go_router + firebase (your firebase-example helped me a lot)
My question:
Is there a way to display a splash-screen during the initialization procedure of firebase? (based on your firebase-example)
Initialization procedure:
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

This is what i want to achieve with go_router:

// provider
final firebaseInitializerProvider = FutureProvider<FirebaseApp>((ref) async {
  logger.info("initialize firebase");
  final firebaseApp = await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  return firebaseApp;
});

// main
void main() async {
  runApp(const ProviderScope(child: MyApp()));
}

// main App
class MyApp extends ConsumerWidget {
  const MyApp({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final firebaseInitializer = ref.watch(firebaseInitializerProvider);
    return MaterialApp.router(
      debugShowCheckedModeBanner: false,
      title: "MyApp",
      home: firebaseInitializer.when(
        data: (data) {
          return const HomeScreen();
        },
        error: (error, stackTrace) => ErrorScreen(error: "$error"),
        loading: () => const LoadingScreen(),
      ),
    );
  }
}

Complete example throws error

Got the complete example in order to check how it works but as soon you tap the login button it will throw an error on this function

 Future<void> login(String email, String password) async {
    state = await AsyncValue.guard<User>(() async {
      return Future.delayed(
        networkRoundTripTime,
        () =>
      );
    });
  }

in the console I can see

type 'AsyncData<User?>' is not a subtype of type 'AsyncValue<User>' of 'previous'

Removing after guard resolves the issue.

Suggested approach with more than one provider to watch?

I have multiple providers that I need to watch to determine whether redirects are needed (e.g. auth provider, email verification provider, etc.). In that scenario using the new sync example, my screen visibly flashes when rebuilding multiple times. I did read the README section about how most rebuilds aren't what they seem, but it seems the current approach may only be meant for a single provider at a time? When I remove everything but a single auth provider the behavior is as expected and there is no flickering or visible rebuilding. Is there a suggested approach or any examples showing how to watch more than one provider? Should I create a combined provider that has every bit of state/property the router needs for its redirect? Thanks so much for making this repo!

Custom/No Transitions

Hey thanks for that repo ๐Ÿ‘

But a simple question, how can I customize or even disable the route transitions? I did not found any information beside using GoRoute but nothing with GoRouteData.

Questions about the build

Hi, sorry to bother you with my questions, but I've been trying for several weeks to finish implementing GoRouter + Riverpod + Firebase and with the code in the repository, it's not quite possible.

I comment my problem below:
In this case, it goes over the logic of the AutoDisposeAsyncNotifier build. One of the main doubts is that I want to read two Streams, one that is if the user is authenticated or not, and another one is a global Stream of the complete User, where I look if it has a field in true or false, to redirect it to a place or another. The problem, is that although the build is done, it is always false at first and then always redirects me to the login and then makes the animation to the home. Wouldn't there be a way to avoid that?

Yes, no, it would be mandatory to add a Splash? My intention was depending on the values, to have one InitialLocation or another.

code_gen always ens up on homepage page, ignoring permissions

Than you for this great repository.

HomeRoute.redirect() is called, but if (state.location == HomeRoute.path) return null; is always returns.
The method _requestMock() is never called.

If I comment if (state.location == HomeRoute.path) return null;, the final userRole = roleListener.read(); will return with null before the _requestMock() method is called.

Could you please fix this?

PS: the permissionsProvider doesn't seam to work also in the complete example

Using the Global Key for firebase example

Hey mate, love the project. It's working flawlessly for my work. I do have one question about it through, and not necessarily a bug report. How does one call the Global Key to navigate?? I'm creating a web app and I want to have simple navigation tabs in the app bar that take the user to the specified page. For example

return AppBar(
   title: TextButton(
     onPressed: isUserSignedIn
         ? () => key.currentState!.pushNamed('/dashboard')
         : () {
             key.currentState!.pushNamed('/preloginhome');
           },
     child: Text(
       'home',

       ),
     ),
   ),

will give me an error Navigator.onGenerateRoute was null, but the route named "/preloginhome" was referenced.
How can we access the routes we put in the routerProvider globally?

Chrome (web) secured content seen for a brief moment

Hi there,

i have Flutter project with Riverpod, go_router. Take a look at this Go router "redirect" part of the code:


  /// Redirects the user when our authentication changes
  String? redirect(BuildContext context, GoRouterState state) {
    if (this.state.isLoading || this.state.hasError) return null;

    final isSplash = state.location == SplashPage.path;

    if (isSplash) {
      return isAuth ? HomePage.path : LoginPage.path;
    }

    final isLoggingIn = state.location == LoginPage.path;
    if (isLoggingIn) return isAuth ? HomePage.path : null;

    final isSigningUp = state.location == SignupPage.path;
    if (isSigningUp) return isAuth ? HomePage.path : null;

    return isAuth ? null : SplashPage.path;
  }

I am testing flutter web at the moment. Let's say when i start the app via VSCode Chrome opens this location: http://localhost:37471/#/splash for a brief moment and then it redirects to
http://localhost:37471/#/login
which is expected behaviour.

The problem is that if i open new tab in chrome and enter manually this URL: http://localhost:37471/#/home

i can see the whole "HomePage" for a brief moment (and i shouldn't see it since i am not logged in) and only then it redirects me to
http://localhost:37471/#/login

Unauthenticated users should never be able to see "HomePage" or other protected pages if they change URL in Chrome manually, that would be a huge security issue, so i have changed the "redirect" part of the code like this:


String? redirect(BuildContext context, GoRouterState state) {
  if (this.state.isLoading || this.state.hasError) return SplashPage.path; 

  final isSplash = state.location == SplashPage.path;
  if (isSplash) {
    return isAuth ? HomePage.path : LoginPage.path;
  }

  final isLoggingIn = state.location == LoginPage.path;
  if (isLoggingIn) return isAuth ? HomePage.path : null;

  final isSigningUp = state.location == SignupPage.path;
  if (isSigningUp) return isAuth ? HomePage.path : null;

  return isAuth ? null : SplashPage.path;
}

...and now it works as expected, at least it looks like so. I am wondering what do you guys thinks. Is this the correct approach or did i break some other scenario(s)?

Best regards!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.