How can I make a wrapper over my private routes, which navigate to screen only when user is authorized, otherwise redirect to login and get back to the original screen after login. How can make this in a generalized way, so that I just reuse it on my other Private future screens?
Asked
Active
Viewed 1,837 times
5
-
Are you using Firebase for login? – Sachin Bhankhar Jul 28 '20 at 07:56
-
No, Simple login from my own node server. No firebase. – Ravi Garg Jul 28 '20 at 07:58
-
Are you using `routes` map in your entry point? – Dmytro Rostopira Jul 28 '20 at 08:12
3 Answers
3
If you are using routes
parameter in your MaterialApp
, you can replace it with following implementation
import 'dart:collection';
import 'package:flutter/widgets.dart';
class ConditionalRouter extends MapMixin<String, WidgetBuilder> {
final Map<String, WidgetBuilder> public;
final Map<String, WidgetBuilder> private;
ConditionalRouter({this.public, this.private});
@override
WidgetBuilder operator [](Object key) {
if (public.containsKey(key))
return public[key];
if (private.containsKey(key)) {
if (MyAuth.isUserLoggedIn)
return private[key];
// Adding next page parameter to your Login page
// will allow you to go back to page, that user were going to
return (context) => LoginPage(nextPage: key);
}
return null;
}
@override
void operator []=(key, value) {}
@override
void clear() {}
@override
Iterable<String> get keys {
final set = Set<String>();
set.addAll(public.keys);
set.addAll(private.keys);
return set;
}
@override
WidgetBuilder remove(Object key) {
return public[key] ?? private[key];
}
}
And use it like that:
MaterialApp(
// ...
routes: ConditionalRouter(
public: {
'/start_page': (context) => StartPage()
},
private: {
'/user_profile': (context) => UserProfilePage()
}
)
)

Dmytro Rostopira
- 10,588
- 4
- 64
- 86
-
Thank you for interesting solution. What are the possibilities to use the async "Auth().isAuth()" function method instead of "MyAuth.isUserLoggedIn" inside your solution? I tried a lot of variants, but no one work :( . Can you help ? – Sergei Eensalu Feb 02 '21 at 13:06
-
1@SergeiEensalu you just have to create wrapper for `Navigator`, that's pretty straightforward to do – Dmytro Rostopira Feb 02 '21 at 13:10
-
thank you for fast answer. I am new in Flutter, can you please give an example? :) – Sergei Eensalu Feb 02 '21 at 13:21
-
1@SergeiEensalu that's not a one-liner comment thing ;) Post this as a separate question, maybe I will find time to answer it later – Dmytro Rostopira Feb 02 '21 at 13:54
-
https://stackoverflow.com/questions/66012904/private-and-public-routers-in-flutter – Sergei Eensalu Feb 02 '21 at 15:44
0
Use StreamBuilder
widget and provide it a Stream of access token/uid if there is no data then return login screen and when user is authenticated then put access token into the stream that will rebuild the StreamBuilder which return the page when user is authenticated.
Use bloc pattern or bloc library for better state management. Hope this will help you.

Sachin Bhankhar
- 900
- 8
- 14
-
I am not using streams from my node server for authentication. Still would take a look on it. – Ravi Garg Jul 28 '20 at 08:10
-
Create a Stream in dart and when user authenticated put data in it. – Sachin Bhankhar Jul 28 '20 at 08:11
-
1I guess, he already has some static var, that says if user is logged in. Also, stream won't solve problem of routing. Also bloc could be an overkill for beginner – Dmytro Rostopira Jul 28 '20 at 08:53
0
Generalised idea, you could make the controller a Static variable
class LoginController{
final Function onContactingServerDone;
LoginController({this.onContactingServerDone,});
bool loggedIn;
login()async {
//contact server,get token or verify token etc
onContactingServerDone();
}
}
and in your screen
LoginController _loginController;
initState(){
_loginController = LoginController(onContactingServerDone: (){
if(_loginController.loggedIn){
Navigator.of(context).pushNamed('privateRoute');
} else {
Navigator.of(context).pushNamed('login');
}
},);
_loginController.login();
}
Widget build(context){
return CircularProgressIndicator();
}

Yadu
- 2,979
- 2
- 12
- 27