0

我有以下代码,我需要在用户重新打开应用程序时让他们保持登录状态。我有来自 firebase 的颤振电话身份验证服务。给出的是验证谷歌手机身份验证的功能。当按下下面提到的 2 个功能时,有一个按钮来获取名为verifyPhoneNumber()&的调用signInWithPhoneNumber()

void verifyPhoneNumber() async {
if (_formKey.currentState!.validate()) {
  setState(() {
    loading = true;
  });
  PhoneVerificationCompleted verificationCompleted =
      (PhoneAuthCredential phoneAuthCredential) async {
    User? user;
    bool error = false;
    try {
      user = (await firebaseAuth.signInWithCredential(phoneAuthCredential))
          .user!;
    } catch (e) {
      print("Failed to sign in: " + e.toString());
      error = true;
    }
    if (!error && user != null) {
      String id = user.uid;
      //here you can store user data in backend
      Navigator.pushReplacement(
          context,
          MaterialPageRoute(
              builder: (context) => PhoneAuthDataNext(
                    phone: phoneNumber,
                  )));
    }
  };

  PhoneVerificationFailed verificationFailed =
      (FirebaseAuthException authException) {
    showToast(authException.message!);
  };
  PhoneCodeSent codeSent =
      (String? verificationId, [int? forceResendingToken]) async {
    showToast('Please check your phone for the verification code.');
    this.forceResendingToken = forceResendingToken;
    _verificationId = verificationId;
  };
  PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
      (String verificationId) {
    _verificationId = verificationId;
  };
  try {
    await firebaseAuth.verifyPhoneNumber(
        phoneNumber: phoneNumber!,
        timeout: const Duration(seconds: 10),
        forceResendingToken:
            forceResendingToken != null ? forceResendingToken : null,
        verificationCompleted: verificationCompleted,
        verificationFailed: verificationFailed,
        codeSent: codeSent,
        codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);
    showOtpScreen = true;
  } catch (e) {
    showToast("Failed to Verify Phone Number: $e");
    showOtpScreen = false;
  }
  setState(() {
    loading = false;
  });
}

}

void signInWithPhoneNumber() async {
    bool error = false;
    User? user;
    AuthCredential credential;
    setState(() {
      loading = true;
    });
    try {
      credential = PhoneAuthProvider.credential(
        verificationId: _verificationId!,
        smsCode: otpEditingController.text,
      );
      user = (await firebaseAuth.signInWithCredential(credential)).user!;
    } catch (e) {
      showToast("Failed to sign in: " + e.toString());
      error = true;
    }
    if (!error && user != null) {
      credential = PhoneAuthProvider.credential(
        verificationId: _verificationId!,
        smsCode: otpEditingController.text,
      );
      UserCredential userCredential =
          await firebaseAuth.signInWithCredential(credential);
      storeTokenAndData(userCredential);

      //here you can store user data in backend
      Navigator.pushReplacement(
          context,
          MaterialPageRoute(
              builder: (context) => PhoneAuthDataNext(
                    phone: phoneNumber,
                    credential: credential,
                  )));
    }
    setState(() {
      loading = false;
    });
  }

请给我一个解决方案。

4

2 回答 2

0

当应用重新启动时,Firebase 已经从本地存储/共享首选项中恢复了用户凭据。但这是一个异步过程,因为它需要调用服务器。

要检测和响应身份验证状态,请按照有关身份验证状态authStateChanges 的文档中所示收听流。

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

您通常需要包装FirebaseAuth.instance.authStateChanges()aStreamBuilder以根据用户是否登录显示正确的 UI 状态。

于 2022-02-02T18:55:20.457 回答
0

Firebase 已经为您处理了“会话”。您可以使用该authStateChanges方法检查身份验证状态并更新您的 UI,就像我在下面的代码中所做的那样

class AuthGate extends StatelessWidget {
  const AuthGate({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (BuildContext context, AsyncSnapshot<User?> snapshot) {
        if (snapshot.hasData) {
          return HomePage();
        }
        return LoginPage();
      },
    );
  }
}
于 2022-02-02T19:26:19.070 回答