Firebase 在启动期间使用 Flutter 重新验证

时间:2021-02-09 02:36:06

标签: firebase flutter firebase-authentication

这个想法是为了让用户即使在用户关闭应用程序并在很晚的时间重新启动之后仍保持登录状态。

我有以下代码登录用户然后尝试存储令牌

Future<User> loginSocialFirebaseGoogle() async {
    GoogleSignInAccount signInResult = await _googleSignIn.signIn();
    GoogleSignInAuthentication auth = await signInResult.authentication;
    final AuthCredential authCredential = GoogleAuthProvider.getCredential(
        idToken: auth.idToken, accessToken: auth.accessToken);
    final AuthResult authResult =
        await _auth.signInWithCredential(authCredential);
    final FirebaseUser firebaseUser = authResult.user;

    assert(!firebaseUser.isAnonymous);
    assert(await firebaseUser.getIdToken() != null);

    final FirebaseUser currentUser = await _auth.currentUser();
    assert(firebaseUser.uid == currentUser.uid);

    final SharedPreferences pref = await SharedPreferences.getInstance();
    pref.setString("idToken", auth.idToken);
    pref.setString("accessToken", auth.accessToken);
    pref.setString("provider", describeEnum(Provider.Google));
    return await authResultToUser(authResult, Provider.Google);
  }

在应用启动期间调用另一部分代码

  Future<User> getCurrentUser() async {
    final SharedPreferences pref = await SharedPreferences.getInstance();
    if (pref != null) {
      AuthCredential authCredential;
      String provider = pref.getString("provider");
      Provider providerEnum;
      if (provider != null) {
        if (provider == describeEnum(Provider.Google)) {
          authCredential = GoogleAuthProvider.getCredential(
              idToken: pref.getString("idToken"),
              accessToken: pref.getString("accessToken"));
          providerEnum = Provider.Google;
        } else if (provider == describeEnum(Provider.Facebook)) {
          authCredential = FacebookAuthProvider.getCredential(
              accessToken: pref.getString("accessToken"));
          providerEnum = Provider.Facebook;
        }
        final AuthResult authResult =
            await _auth.signInWithCredential(authCredential);
        return await authResultToUser(authResult, providerEnum);
      }
    }
    return null;
  }

但是我在 _auth.signInWithCredential(authCredential) 期间遇到错误,错误是

`ERROR_INVALID_CREDENTIAL` - If the credential data is malformed or has expired.

看起来我在 SharedPreferences 中存储的内容是错误的。知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

<块引用>

这个想法是为了让用户即使在用户关闭应用程序并在很晚的时间重新启动之后仍保持登录状态。

Firebase 已经让用户保持登录状态,并自动尝试恢复他们的会话,而无需您为其编写任何代码。

但由于这可能需要调用服务器,因此您可能在该过程完成之前正在阅读 _auth.currentUser。要正确检测身份验证状态,请使用 authStateChanges 侦听器,如 documentation 中所示:

FirebaseAuth.instance
  .authStateChanges()
  .listen((User user) {
    if (user == null) {
      print('User is currently signed out!');
    } else {
      print('User is signed in!');
    }
  });
相关问题