首页 文章

使用导航处理Flutter中的身份验证状态

提问于
浏览
1

我正在使用Google登录来处理Flutter应用中的用户身份验证 . 这适用于单视图应用程序(无路由),但只要我尝试添加一些路由并有效地管理路由,事情变得非常棘手 .

如果我错了,请纠正我,但我认为我想要的是顶级的有状态小部件,它控制我签名的变量和auth方法 . 这个顶级有状态小部件也控制我的路由 . 以下是我当前设置的一些片段:

class SignInState extends State<SignIn> {
  GoogleSignInAccount _currentUser;
  ...

  Future<Null> _handleSignIn() async {
    try {
      await _googleSignIn.signIn();
    } catch (error) {
      print(error);
    }
  }

  Future<Null> _handleSignOut() async {
    _googleSignIn.disconnect();
  } 

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: _pageTitle,
      home: new Home(),
      routes: <String, WidgetBuilder> {
        "/": (BuildContext context) => new Home(),
        "/settings": (BuildContext context) => new Settings(),
        "/login": (BuildContext context) => new Login()
      },
      ...
    );
  }
}

我的假设是我的状态会被传递到嵌套的小部件,但我没有在 Home() 中看到 _currentUser 变量 .

在其他框架中,您可以指定在路由加载上运行的方法,如果有一种优雅的方法来检查在加载路由之前是否存在_currentUser,那么我会很高兴,这样如果用户没有登录,我就可以推送新的路由 .

如果有人在Flutter应用程序中结合路由和身份验证的经验,我真的很欣赏朝着正确方向迈出的一步 . 我发现的大多数教程都是针对其中一个 .

谢谢!

1 回答

  • 2

    如果您将 SignIn 小部件设为InheritedWidget,并向其中添加包含用户状态的某些属性(例如 userState ),则可以向其中添加如下方法:

    static UserState of(BuildContext context, { bool nullOk: false }) {
        assert(context != null);
        assert(nullOk != null);
        final SignIn signInWidget = context.inheritFromWidgetOfExactType(SignIn);
        if (signInWidget != null)
          return signInWidget.userState;
        if (nullOk)
          return null;
        throw new FlutterError(
          'Attempted to find UserState without a SignInWidget parent.\n'
          'The context used was:\n'
          '  $context'
        );
    }
    

    然后你可以打电话

    SignIn.of(context)
    

    在你的路线中获得 UserState .

    还有其他方法可以做到这一点 - 例如,将您的数据放在redux存储中,或创建回调链(例如,将 SignInWidget 上的回调暴露给子路径) . 这可能是最干净的内置方式,特别是如果您计划将这个小部件直接放在树的顶部 - 但如果您采用了其他一些状态管理策略(比如使用redux),那么您可能想考虑使用它 .

相关问题