I have created authentication with google on first time start up of app and I have my own _authenticatedUser
which stores user token for further requests.
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
Future<String> signInGoogle() async {
GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
GoogleSignInAuthentication gsa = await googleSignInAccount.authentication;
FirebaseUser user = await firebaseAuth.signInWithGoogle(
idToken: gsa.idToken, accessToken: gsa.accessToken);
var token = await user.getIdToken();
_authenticatedUser = User(id: user.uid, email: user.email, token: token, photo: user.photoUrl);
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('loggedin', 'Google');
prefs.setString('token', token);
prefs.setString('userEmail', user.email);
prefs.setString('userId', user.uid);
prefs.setString('userImage', user.photoUrl);
return 'okay';
}
I then call getCurrentUser()
function in initState()
to check user is there or not but when the token expires then I get faulty user with expired token.
Future<FirebaseUser> getCurrentUser() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
if (user != null) {
print('signed in');
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString('token');
String uid = prefs.getString('userId');
String email = prefs.getString('userEmail');
String photo = prefs.getString('photo');
_authenticatedUser = User(email: email, id: uid, token: token, photo: photo);
return user;
} else {
print('user is null');
return null;
}
}
Please someone explain how to fix this?
I redirect user on the basis of return of getCurrentUser
in main.dart file.
It only refreshes when : When user Uninstall/Reinstall the app or Clears App Data. You manually delete FCM Instance using FirebaseMessaging(). deleteInstanceID()
Firebase ID tokens are short lived and last for an hour; the refresh token can be used to retrieve new ID tokens. Refresh tokens expire only when one of the following occurs: The user is deleted.
Today I had the same issue in my app with graphQl. The answer was found in documentation here https://firebase.google.com/docs/auth/admin/manage-sessions
We can see (copy-paste from documentation):
So, there is a lot of different ways to solve this problem. We can check state and revoke token, we can mutate state with Provider or Inherited widgets, we can use BLoC pattern for keeping it fresh.
But, in any case we will have one issue - what if user close app and open it after 2-3 days? Of course user have to be automatically authenticated and he shouldn't notice anything.
My decision was to use update token method, for your case it could look like:
void updateToken() {
if (firebaseAuth.currentUser() != null) {
firebaseAuth.currentUser().then((val) {
val.getIdToken(refresh: true).then((onValue) {
// here you can mutate state to BLoC or Provider
// or Inherited widget
// for example - authBloc.passFirebaseToken.add(onValue.token);
});
});
}
}
That's it. You can place all this auth methods to Singleton and use them on any page where is issue is possible.
I got the same issue and fixed it by:
Future refreshFirebaseUser() async {
if (auth.currentUser != null) {
final user = auth.currentUser;
final idTokenResult = await user!.getIdTokenResult(true);
return idTokenResult;
}
}
Just call the function ideally during login/signup
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