Closed kornha closed 2 years ago
Why is the auth state indeterminate? Can you post a minimal sample that shows the login page for a "hot second"?
Sure. The authState will be intermediate because the server has yet to respond with authenticated or unauthenticated. For example, here is a changenotifier that this would exist in:
class AuthState extends ChangeNotifier {
AuthStatus status = AuthStatus.unknown;
final Auth _auth = Auth();
User? authUser;
bool get isLoggedIn => status == AuthStatus.authenticated;
bool get isLoading =>
status == AuthStatus.unknown || status == AuthStatus.authenticating;
AuthState.instance() {
status = AuthStatus.unknown;
_auth.auth.authStateChanges().listen((user) async {
authUser = user;
if (user == null) {
status = AuthStatus.unauthenticated;
} else {
status = AuthStatus.authenticated;
}
notifyListeners();
});
}
}
Note that, in the above, before a server response we will have state == unknown.
The problem with showing the login page with a loading indicator -> redirecting to an authenticated page, is that it creates a race condition. The loading indicator and the redirect will both listen on a change in authState. So if the loading indicator hears the change first, it will vanish, then show the login page (for an instant.. so I guess I could do a 'sleep' here but certainly not ideal), then redirect to the authenticated page. Does that make sense? I can image capture if not.
A subtle annoyance with my proposed solution as well is that it requires deeplinking to be implemented in the loading path.
May this help ? (I used null
for AuthState.unknown
for simplicity)
This could be improved of course but I think the core idea is there
I'm sorry. I'm looking for a complete minimal repro, ie an app that I can load into my ide and run.
Oh actually I was giving a solution to @kornha ^^
Ha. And I was asking @kornha for a repro so I could understand the problem. One step ahead as usual @lulupointu. : )
Killer package, thanks so much once again. I wanted to run by an important use case here for myself, and I imagine for others, and hopefully get your input.
If I follow the sample, I get something like this:
This works great, the only problem is, if I refresh the page the authstate is momentarily interdeterminate. I can use this state and assume the user is logged out, which the above code down, but then for a hot second it shows the login screen. I would rather it show a loading screen in this intermediate auth state.
There's 2 approaches I can think of to address this use case. 1: in my actual login view, show a loading screen during an intermediate authState. This does not work, as then, for a very hot second, the screen will update to the login screen before the router redirects to the authenticated page 2: A bit hacky, but to do this on the router level, something like:
This works perfectly from a UX standpoint, but has the minor problem that it includes an intermediate "loading" in the auth path, and just feels hacky. Is this the preferred way to solve this problem?