Authentication 飞溅屏颤振认证流程

Authentication 飞溅屏颤振认证流程,authentication,flutter,dart,Authentication,Flutter,Dart,我创建了一个AuthProivder,我有多个身份验证状态可供监听 我创建了一个splashscreen,首先加载并检查身份验证状态,然后根据当前状态将其导航到正确的页面 class SplashScreen extends StatefulWidget { static const String id = "splashscreen"; @override _SplashScreenState createState() => _SplashScreenState(); }

我创建了一个AuthProivder,我有多个身份验证状态可供监听

我创建了一个splashscreen,首先加载并检查身份验证状态,然后根据当前状态将其导航到正确的页面

class SplashScreen extends StatefulWidget {
  static const String id = "splashscreen";

  @override
  _SplashScreenState createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void didChangeDependencies() async {
    final status = Provider.of<AuthProvider>(context).status;
    print(status.toString());
    WidgetsBinding.instance.addPostFrameCallback((_) {
      switch (status) {
        case Status.Uninitialized:
          Navigator.pushReplacementNamed(context, WelcomeScreen.id);
          break;
        case Status.Unauthenticated:
        case Status.Authenticating:
          Navigator.pushReplacementNamed(context, LoginScreen.id);
          break;
        case Status.Authenticated:
          Navigator.pushReplacementNamed(context, LoadAuthData.id);
          break;
      }
    });
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

类SplashScreen扩展StatefulWidget{
静态常量字符串id=“splashscreen”;
@凌驾
_SplashScreenState createState()=>\u SplashScreenState();
}
类的状态扩展了状态{
@凌驾
void didChangeDependencies()异步{
最终状态=Provider.of(context).status;
打印(status.toString());
WidgetsBinding.instance.addPostFrameCallback((){
开关(状态){
案例状态。未初始化:
Navigator.pushReplacementNamed(上下文,WelcomeScreen.id);
打破
案例状态。未经验证:
案例状态。验证:
Navigator.pushreplacementname(上下文,LoginScreen.id);
打破
案例状态。已验证:
Navigator.pushReplacementNamed(上下文,LoadAuthData.id);
打破
}
});
super.didChangeDependencies();
}
@凌驾
小部件构建(构建上下文){
返回容器();
}
}
授权提供者

enum Status { Uninitialized, Authenticated, Authenticating, Unauthenticated }

class AuthProvider with ChangeNotifier {
  FirebaseAuth _auth;
  FirebaseUser _user;
  GoogleSignIn _googleSignIn;
  Status _status = Status.Uninitialized;
  Firestore _firestore = Firestore.instance;
  String _token;

  AuthProvider.instance()
      : _auth = FirebaseAuth.instance,
        _googleSignIn = GoogleSignIn() {
    _auth.onAuthStateChanged.listen(_onAuthStateChanged);
  }

  Status get status => _status;
  FirebaseUser get user => _user;
  String get token => _token;

  void updateIdToken() {
    if (_auth.currentUser() != null) {
      _auth.currentUser().then((val) {
        val.getIdToken(refresh: true).then((onValue) {
          _token = onValue.token;
          notifyListeners();
        });
      });
    }
  }

  Future<bool> signIn(String email, String password) async {
    try {
      _status = Status.Authenticating;
      notifyListeners();
      await _auth.signInWithEmailAndPassword(email: email, password: password);
      return true;
    } catch (e) {
      _status = Status.Unauthenticated;
      notifyListeners();
      return false;
    }
  }

  Future<bool> registerUser(String email, String password) async {
    try {
      _status = Status.Authenticating;
      notifyListeners();
      final AuthResult _authResult = await _auth.createUserWithEmailAndPassword(
          email: email, password: password);
      _firestore
          .collection('users')
          .document(_authResult.user.uid)
          .setData({'email': _authResult.user.email});
      return true;
    } catch (e) {
      _status = Status.Unauthenticated;
      notifyListeners();
      return false;
    }
  }

  Future<bool> resetEmailLink(String email) async {
    try {
      _status = Status.Authenticating;
      notifyListeners();
      await _auth.sendPasswordResetEmail(email: email);
      return true;
    } catch (e) {
      _status = Status.Unauthenticated;
      notifyListeners();
      return false;
    }
  }

  Future<bool> signInWithGoogle() async {
    try {
      _status = Status.Authenticating;
      notifyListeners();
      final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
      final GoogleSignInAuthentication googleAuth =
          await googleUser.authentication;
      final AuthCredential credential = GoogleAuthProvider.getCredential(
        accessToken: googleAuth.accessToken,
        idToken: googleAuth.idToken,
      );
      await _auth.signInWithCredential(credential);
      return true;
    } catch (e) {
      print(e);
      _status = Status.Unauthenticated;
      notifyListeners();
      return false;
    }
  }

  Future signOut() async {
    _auth.signOut();
    _googleSignIn.signOut();
    _status = Status.Unauthenticated;
    notifyListeners();
    return Future.delayed(Duration.zero);
  }

  Future<void> _onAuthStateChanged(FirebaseUser firebaseUser) async {
    if (firebaseUser == null) {
      _status = Status.Unauthenticated;
    } else {
      firebaseUser.getIdToken().then((onValue) => _token = onValue.token);
      _user = firebaseUser;
      updateIdToken();
      _status = Status.Authenticated;
    }
    notifyListeners();
  }
}
enum状态{未初始化、已验证、正在验证、未验证}
使用ChangeNotifier类AuthProvider{
FirebaseAuth_auth;
FirebaseUser\u用户;
谷歌签名(googlesign);;
状态_Status=状态。未初始化;
Firestore _Firestore=Firestore.instance;
字符串标记;
AuthProvider.instance()
:_auth=FirebaseAuth.instance,
_googleSignIn=googleSignIn(){
_auth.onAuthStateChanged.listen(_onAuthStateChanged);
}
状态获取状态=>\u状态;
FirebaseUser获取用户=>\u用户;
字符串get token=>\u token;
void updateIdToken(){
如果(_auth.currentUser()!=null){
_auth.currentUser().then((val){
val.getIdToken(刷新:true)。然后((onValue){
_token=onValue.token;
notifyListeners();
});
});
}
}
未来登录(字符串电子邮件、字符串密码)异步{
试一试{
_状态=状态。身份验证;
notifyListeners();
等待使用email和password(电子邮件:电子邮件,密码:password)进行身份验证登录;
返回true;
}捕获(e){
_状态=状态。未经验证;
notifyListeners();
返回false;
}
}
未来注册服务器(字符串电子邮件、字符串密码)异步{
试一试{
_状态=状态。身份验证;
notifyListeners();
final AuthResult\u AuthResult=wait\u auth.createUserWithEmailAndPassword(
电子邮件:电子邮件,密码:密码);
_火库
.collection('用户')
.document(_authResult.user.uid)
.setData({'email':_authResult.user.email});
返回true;
}捕获(e){
_状态=状态。未经验证;
notifyListeners();
返回false;
}
}
未来重置电子邮件链接(字符串电子邮件)异步{
试一试{
_状态=状态。身份验证;
notifyListeners();
等待授权发送密码重置电子邮件(电子邮件:email);
返回true;
}捕获(e){
_状态=状态。未经验证;
notifyListeners();
返回false;
}
}
未来登录使用Google()异步{
试一试{
_状态=状态。身份验证;
notifyListeners();
final GoogleSignInAccount googleUser=wait_googleSignIn.signIn();
最终谷歌签名认证=
等待googleUser.authentication;
final AuthCredential credential=GoogleAuthProvider.getCredential(
accessToken:googleAuth.accessToken,
idToken:googleAuth.idToken,
);
使用凭证(凭证)等待授权登录;
返回true;
}捕获(e){
印刷品(e);
_状态=状态。未经验证;
notifyListeners();
返回false;
}
}
Future signOut()异步{
_auth.signOut();
_googleSignIn.signOut();
_状态=状态。未经验证;
notifyListeners();
返回未来。延迟(持续时间为零);
}
Future\u onAuthStateChanged(FirebaseUser FirebaseUser)异步{
if(firebaseUser==null){
_状态=状态。未经验证;
}否则{
firebaseUser.getIdToken()。然后((onValue)=>\u token=onValue.token);
_用户=firebaseUser;
updateIdToken();
_status=status.Authenticated;
}
notifyListeners();
}
}
我发现,最初状态是单元化的,它将页面发送到欢迎屏幕,几秒钟后状态变为已验证,然后移动到LoadAuthData屏幕

有没有比我目前的做法更好的方法来实现这一点,我需要处理“新用户==未登录,当前用户==未认证/身份验证和登录用户”

我试图一眨眼不显示欢迎屏幕,然后导航到loadAuth或登录屏幕


谢谢

如果是第一次使用firebase auth并检查当前用户!=null,我可以使用SharePreFrence并保存一个值