Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update Firebase token in Flutter application after it expires and store it?

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.

like image 436
tensor Avatar asked Jan 20 '19 18:01

tensor


People also ask

How do you refresh a Firebase token in flutter?

It only refreshes when : When user Uninstall/Reinstall the app or Clears App Data. You manually delete FCM Instance using FirebaseMessaging(). deleteInstanceID()

Does Firebase token expire?

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.


2 Answers

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):

  1. Firebase Authentication sessions are long lived.
  2. Firebase ID tokens are short lived and last for an hour.

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.

like image 113
awaik Avatar answered Oct 30 '22 00:10

awaik


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

like image 45
Glen Agak Avatar answered Oct 30 '22 01:10

Glen Agak