如何在 Flutter 应用程序中更新 Firebase 令牌并存储它?

Posted

技术标签:

【中文标题】如何在 Flutter 应用程序中更新 Firebase 令牌并存储它?【英文标题】:How to update Firebase token in Flutter application after it expires and store it? 【发布时间】:2019-06-14 05:24:03 【问题描述】:

我已经在第一次启动应用程序时使用谷歌创建了身份验证,并且我有自己的_authenticatedUser,它存储用户令牌以供进一步请求。

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';
  

然后我在initState() 中调用getCurrentUser() 函数来检查用户是否存在,但是当令牌过期时,我会得到带有过期令牌的错误用户。

  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;
    
  

请有人解释一下如何解决这个问题?

我根据main.dart文件中getCurrentUser的返回重定向用户。

【问题讨论】:

您找到解决方案了吗?我有类似的问题..插件只返回 idtoken 但是当用户登录谷歌时我需要刷新令牌.. @user2570135 你找到解决方案了吗?我遇到了同样的问题。我需要 refreshToken,已经有 idToken 并且有效! 【参考方案1】:

今天,我在使用 graphQl 的应用程序中遇到了同样的问题。答案在此处的文档中找到https://firebase.google.com/docs/auth/admin/manage-sessions

我们可以看到(从文档中复制粘贴):

    Firebase 身份验证会话长期存在。 Firebase ID 令牌是短暂的,持续一个小时。

所以,有很多不同的方法可以解决这个问题。我们可以检查状态并撤销令牌,我们可以使用 Provider 或 Inherited 小部件改变状态,我们可以使用 BLoC 模式来保持它的新鲜度。

但是,无论如何我们都会遇到一个问题——如果用户关闭应用并在 2-3 天后打开它会怎样?当然,用户必须自动进行身份验证,他不应该注意到任何事情。

我的决定是使用更新令牌方法,对于您的情况,它可能如下所示:

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

就是这样。您可以将所有这些身份验证方法放在 Singleton 中,并在可能出现问题的任何页面上使用它们。

【讨论】:

【参考方案2】:

我遇到了同样的问题并通过以下方式解决了它:

Future refreshFirebaseUser() async 
  if (auth.currentUser != null) 
    final user = auth.currentUser;
    final idTokenResult = await user!.getIdTokenResult(true);
    return idTokenResult;
  

最好在登录/注册期间调用该函数

【讨论】:

【参考方案3】:

我遇到了同样的问题,我所做的是:

在我的主要方法中,我检查当前用户是否为空,即如果没有用户登录,然后我将用户重定向到他们有机会登录或注册的登录页面。如果用户不为空,那么我从存储在我的数据库中的位置获取用户令牌并获取当前用户令牌,如果它们不同或者如果存储在数据库中的用户令牌为空(即,从来没有首先是一个)然后我用当前的令牌更新令牌。

在我的登录中,我也这样做。成功登录后,我检查为该用户存储的令牌是否不同,如果不同,我更新它。

在我的注册中,我只需获取设备的令牌并将其与用户信息一起存储。我希望这有帮助。我也知道这是一个老问题,但我遇到了这个问题,并认为我会为任何正在寻找的人分享一个可能的解决方案。

【讨论】:

令牌过期后如何更新。?如果您的数据库中的一个商店是 idtoken 并且它过期了,基本上。如何从 idToken 获取刷新令牌 不知道有没有办法“从idToken获取刷新令牌”。我所做的是在 main 方法中,我获取当前令牌并将其与我在数据库中拥有的令牌进行比较。如果它不同,我用最新的更新。您是否在寻求获取最新令牌的方法?

以上是关于如何在 Flutter 应用程序中更新 Firebase 令牌并存储它?的主要内容,如果未能解决你的问题,请参考以下文章

如何在项目中使用 firebase 和 firebase 功能的现有 Flutter 应用程序中更新包名称?

如何在 Flutter 中更新 AnimatedList 中的数据

在 Flutter 中将 Firebase 数据作为 Listview 构建器获取

即使 Flutter 应用程序在后台,如何自动响应 Firebase Document Stream 更新? [关闭]

如何在邮件被验证时更新Firebase用户流的数据(Flutter)

如何在邮件被验证时更新Firebase用户流的数据(Flutter)