简体   繁体   中英

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.

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.

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

I ran into the same issue and what I did was this:

In my main method, I check if the current user is null, ie if there is no user signed in, then I redirect the user to the landing page where they have the chance to login or signup. If the user is not null, then I fetch the user token from the place where it is stored in my database and fetch the current user token, if they are different or if the one stored in the database is null(ie, there was never one in the first place) the then I update the token with the current one.

In my login, I do the same. After logging in successfully, I check if the token stored for that user is different and if it is, I updated it.

In my signup, I simply get the token for the device and store it with the user's information. I hope this helps. I also know its an old question but I ran into the problem and thought I would share a possible solution for anyone who is looking.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM