I am trying to create a Login using Provider pattern. This is what I've tried so far...
First this is my UserRepository:
enum Status { Uninitialized, Authenticated, Authenticating, Unauthenticated }
class UserRepository with ChangeNotifier{
User user;
Status _status =Status.Uninitialized;
Status get status => _status;
User get authUser => user;
Future<bool> signIn(String email, String password) async {
try{
var body = jsonEncode({
'email': email,
'password': password
});
var res = await http.post(('http://192.168.178.35:8000/auth/login'),
body: body,
headers: {
"Accept": "application/json",
"content-type": "application/json"
});
var response = jsonDecode(res.body);
if(response.status == 200)
{
notifyListeners();
return true;
}
}
catch(e)
{
_status = Status.Unauthenticated;
notifyListeners();
return false;
}
}
}
And this should be my entry page (HomePage):
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<UserRepository>(
child: Consumer(
builder: (context, UserRepository user, _) {
switch (user.status) {
case Status.Uninitialized:
return Login();
case Status.Unauthenticated:
case Status.Authenticating:
return Login();
case Status.Authenticated:
return DriverDashboard(user: user.user);
}
},
),
);
}
}
And after I try to run the app I get this error:

Does anyone have any idea why is this happening? Is this correct way how to implement ChangeNotifierProvider?
I am trying to follow this tutorial https://medium.com/flutter-community/flutter-firebase-login-using-provider-package-54ee4e5083c7 ...
However, except Firebase I use custom created RESTful API as a backend.
Although, this error message is not intuitive, I guess you might return a null in the builder function.
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<UserRepository>(
child: Consumer(
builder: (context, UserRepository user, _) {
//NOTICE HERE: What If your user is null?
switch (user.status) {
case Status.Uninitialized:
return Login();
case Status.Unauthenticated:
case Status.Authenticating:
return Login();
case Status.Authenticated:
return DriverDashboard(user: user.user);
}
// return SplashPageHere();
},
),
);
}
}
You should give a splash page, or something that return Widget for builder.
Edit:
Here is the example to use ChangeNotifierProvider
ChangeNotifierProvider<AppState>(
builder: (_) => AppState(),
child: MyHomePage(),
));
And this is the code you post from medium:
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
builder: (_) => UserRepository.instance(),
child: Consumer(
builder: (context, UserRepository user, _) {
switch (user.status) {
case Status.Uninitialized:
return Splash();
case Status.Unauthenticated:
case Status.Authenticating:
return LoginPage();
case Status.Authenticated:
return UserInfoPage(user: user.user);
}
},
),
);
}
ChangeNotifierProvider should contain a builder and child, That's why you always have null for your user...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With