Coffee & Code - Rewriting My App, GetX to Riverpod

Coffee & Code - Rewriting My App, GetX to Riverpod

Exploring Riverpod as an alternative to GetX for Flutter state management, with practical examples of AsyncNotifiers and Providers.


Sample Image
Cappuccino from The Coffee House at West End in Houston, TX.

In discussions about State Management, I’ve usually leaned towards GetX and Bloc. However, I’ve been recently exploring Riverpod, a State Management tool that, in some ways, is simpler than the other two.

Sample Image
Riverpod official website.

From my understanding, AsyncNotifiers and Notifiers hold the state, which is the data about a particular item.

Sample Image
Demo of the new authentication flow using a provider instead of GetX.

Meanwhile, Providers grant us access to these states from anywhere at any time.

Sample Image
Flutter Riverpod State Management with the creator, Remi Rousselet.

To illustrate this with an analogy, think of Riverpod as a world in a different galaxy.

/// Notifier that handles authentication.
class AuthAsyncNotifier extends AsyncNotifier<User?> {
  // FirebaseAuth instance.
  final FirebaseAuth _auth = FirebaseAuth.instance;
  
  // This state holds a nullable auth user.
  @override
  User? build() => _auth.currentUser;
  AuthAsyncNotifier(): super() {
    // Update state based on auth changes.
    _auth.authStateChanges().listen(
      (user) => user == null
        ? state = const AsyncData(
          null,
        : _prepareUser(
          user,
          ),
        );
  }
}

The Notifiers are the data in that world, and the Providers are the gateways that link our world to that one.

/// Providers "provide" data.
class Providers {
  // This one "provides" an auth user.
  static final authAsyncNotifierProvider =
    AsyncNotifierProvider<AuthAsyncNotifier, User?>(
      AuthAsyncNotifier.new,
    );
}

This system lets us access whatever data we need whenever we desire it. As a result, the files for the views and controllers of the app are now much more streamlined.

GoRouter appRoutes(bool isAuthenticated) => GoRouter(
  // Redirect to login screen if user is not authenticated.
  redirect: (context, state) =>
    isAuthenticated ? null: '/${Globals.routeLogin}',
    // Default location is the dashboard screen.
    initialLocation: '/${Globals.routeDashboard}',
    // Routes provided by the app.
    routes: [      GoRoute(
        path: '/${Globals.routeLogin}',
        name: Globals.routeLogin,
        builder: (context, state) => const LoginScreen(),
      ),
      GoRoute(
        path: '/${Globals.routeDashboard}',
        name: Globals.routeDashboard,
        builder: (context, state) => DashboardScreen(),
      ),
    ],
  );

Related posts
Coffee & Code - Firestore Sorting & Toast Messages

Coffee & Code - Firestore Sorting & Toast Messages

Read more
Coffee & Code - Building an AR Solar System with Flutter and ARKit

Coffee & Code - Building an AR Solar System with Flutter and ARKit

Read more
Coffee & Code - Quote Keeper's Edit Quote UI Update

Coffee & Code - Quote Keeper's Edit Quote UI Update

Read more
Coffee & Code - Implementing Tutorial Coach Mark for App Onboarding

Coffee & Code - Implementing Tutorial Coach Mark for App Onboarding

Read more