Issue
I’m new to Flutter/Dart and trying to create a basic authentication service. My plain is to make my main application listen to a stream which will emit the user when authentication actions take place. This is how a lot of the Firebase examples work, the only difference is that I want to connect directly to my own API.
To do this I’ve created an AuthService, but can’t actually seem to get it working.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider<AuthService>(
create: (_) => AuthService(),
child: MaterialApp(
home: AuthWidget()
)
);
}
}
class AuthWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final authService = Provider.of<AuthService>(context);
authService.getUser();
// wrap the application in a Stream that watches for the authentication state
// to change. On authentication state change,
return StreamBuilder<User>(
stream: authService.onAuthStateChanged,
builder: (context, snapshot) {
// check to ensure that the connectionState is active
if (snapshot.connectionState == ConnectionState.active) {
final user = snapshot.data;
return user == null ? Login() : Home();
}
return Login();
}
);
}
}
class AuthService {
User currentUser;
Future<User> getUser() {
return Future.value(currentUser);
}
void login(User user) {
currentUser = user;
}
void logout() {
currentUser = null;
}
Stream<User> get onAuthStateChanged {
return Stream.fromFuture(getUser());
}
}
What I want to achieve
At the top level MyApp
, I’d like to be able to listen for changes in authentication using the AuthProvider. I should be able to access the authentication provider anywhere, e.g.
final auth = Provider.of<AuthService>(context, listen: false);
// log the user in
auth.login(user);
// log the user out
auth.logout(user);
// get the current authenticated user
auth.getUser();
And use this to manage the application. The problem I am having with my existing code is that the Stream status is instantly marked as done, so no further changes are ever emitted from the onAuthStateChanged
. I actually need my AuthWidget
to continue listening throughout the lifetime of the application, so that I can respond to login/logout events and change the UI accordingly.
Any help is greatly appreciated!
Solution
Ok, I managed to come up with a solution in the end using slightly different techniques. Thanks to this article by Aaron K Saunders for the pointers – https://dev.to/aaronksaunders/simple-login-flow-in-flutter-then-firebase-part-one-29n6
Essentially my AuthService
now implements a ChangeNotifier and I can use this around the app to check auth, show different routes, get current user etc.
Answered By – Chris
Answer Checked By – Gilberto Lyons (FlutterFixes Admin)