Go Router + Riverpod Tutorials Series 4: Role Based Redirection

Search for a command to run...

No comments yet. Be the first to comment.
In here we'll look at a series of tutorials covering Go Router and Riverpod together.
Redirection is one of the best features of Go Router. So in total we are going to look at 5 tutorials which explore redirection in increments of complexity. This article marks our first tutorial. Step 1: Define an AuthNotifier and authProvider using ...
While I generally write about Flutter. This problem has been bugging me for a while and there seem to be limited resources to find a solution. So for anyone who is looking for a solution. Here you go: Type edge:flags into the address bar and open it...
In this tutorial, we’ll go through covering interceptor, which is a very crucial feature of Dio. You can find the entire source code for the project here: dio_tasker Understanding Interceptors: What is an interceptor? An interceptor in Dio is a powe...

In this part, we’ll enhance our Task Manager app by parsing JSON responses and handling different types of errors. We’ll use Dio’s built-in error handling mechanisms. You can find the source code of the entire app here: dio_tasker Parsing JSON Respon...

While building apps in Flutter is extremely fluid and wonderfully intuitive. We obviously know that we can’t build the next TikTok or Twitter by only building offline apps. Which is why we absolutely need internet capabilities in our Flutter apps. Th...

Understanding when to use setState in Flutter is crucial for managing our app’s state effectively. Here’s a detailed guide: When to use setState ? Updating the UI: Use setState when we need to update the UI in response to changes in the internal sta...

Now let's take a look at redirection depending on user roles
Source code: role_based_redirection
Now, Let's update our files starting with :
This is the updated AuthNotifier
class AuthNotifier extends StateNotifier<Map<String, dynamic>> {
AuthNotifier() : super({'loggedIn': false, 'role': 'guest'});
void login(String role) {
state = {'loggedIn': true, 'role': role};
print('State change to true, Logged in as $role');
}
void logout() {
state = {'loggedIn': false, 'role': 'guest'};
print('State change to false, Logged out');
}
}
This is the updated authProvider
final authProvider = StateNotifierProvider<AuthNotifier, Map<String, dynamic>>((ref) {
return AuthNotifier();
});
First since we are getting a map instead of bool. Let's get a update our redirectIfNotLoggedIn()
FutureOr<String?> redirectIfNotLoggedIn(ProviderRef ref) {
final loggedIn = ref.watch(authProvider)['loggedIn'];
if (!loggedIn) {
return '/login';
}
return null;
}
Now for the AdminPage() route. Let's make sure that only admin role should be able to see the page. So we'll update the redirect of the /admin route.
GoRoute(
path: '/admin',
builder: (context, state) => const AdminPage(),
redirect: (context, state) {
final loggedIn = ref.watch(authProvider)['loggedIn'];
final role = ref.watch(authProvider)['role'];
if (!loggedIn) {
return '/login';
}
if(role != 'admin'){
return '/home';
}
return null;
},
)
Now let's update our existing pages to use the new roles property.
class HomePage extends ConsumerWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
title: const Text('GRT Redirect'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Home Page'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
ref.read(authProvider.notifier).logout();
},
child: const Text('Logout')),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
context.go('/home/profile');
},
child: const Text('Go to Profile')),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
context.go('/home/settings');
},
child: const Text('Go to Settings')),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
context.go('/admin');
},
child: const Text('Go to Admin')),
],
),
),
);
}
}
We are updating the login page to allow logging in as either a regular user or an admin.
class LoginPage extends ConsumerWidget {
const LoginPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
title: const Text('GRT Login'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('This is Login Page'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
ref.read(authProvider.notifier).login('user');
},
child: const Text('Login as User')),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
ref.read(authProvider.notifier).login('admin');
},
child: const Text('Login as Admin')),
],
),
),
);
}
}
Alright so let's test the code

So this code works perfect. As always you can find the code for this tutorial here: role_based_redirection