代码之家  ›  专栏  ›  技术社区  ›  Shady Aziza

如何正确设置基于身份验证的导航

  •  2
  • Shady Aziza  · 技术社区  · 9 年前

    我一直在试图找出正确的方法,通过我的应用程序设置导航的基础上的价值 FirebaseAuth (即:仅在用户登录后导航)

    User 类是我应用程序中的第一个页面,它在检查是否有 currentUser

        class User extends StatefulWidget {
          @override
          _UserState createState() => new _UserState();
        }
    
        class _UserState extends State<User> {
           FirebaseUser _user;
    
    
          @override
          initState() {
            super.initState();
            _checkUser();
          }
    
          @override
          Widget build(BuildContext context) {
            return _user == null? new SignInPage(): new HomePage();
          }
    
          _checkUser ()async {
            FirebaseUser user = await FirebaseAuth.instance.currentUser();
            setState((){
              this._user = user;
            });
    
          }
        }
    

    当应用程序第一次启动时,它会加载 SignInPage

    class SignInPage extends StatefulWidget {
      @override
      _SignInPageState createState() => new _SignInPageState();
    }
    
    class _SignInPageState extends State<SignInPage> {
    
      final FirebaseAuth _auth = FirebaseAuth.instance;
      final GoogleSignIn _googleSignIn = new GoogleSignIn();
    
    
       _handleSignIn() async{
    
        final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
        final GoogleSignInAuthentication googleAuth =
        await googleUser.authentication;
        final FirebaseUser user = await _auth.signInWithGoogle(
          accessToken: googleAuth.accessToken,
          idToken: googleAuth.idToken,
        );
        assert(user.email != null);
        assert(user.displayName != null);
        assert(!user.isAnonymous);
        assert(await user.getToken() != null);
        print (user);
    
             }
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
            appBar: new AppBar(
                title: new Text("Sign In"),
                centerTitle: true,
                leading: new Container(),
                backgroundColor: new Color.fromARGB(255,17,165,137)),
            body: new Container(
                child: new Center(
                    child:
                    new Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        new Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          mainAxisSize: MainAxisSize.max,
                          children: <Widget>[new RaisedButton(
                              child: new Container(
                                  child: new Row(children: <Widget>[
                                    new Container(
                                        child: new Image(
                                          image: new NetworkImage(
                                              "https://maxcdn.icons8.com/Share/icon/Logos//google_logo1600.png"),
                                        ),
                                        margin: new EdgeInsets.only(right: 8.0)),
                                    new Text("Login with Google", style: new TextStyle(color: Colors.redAccent)),
                                  ], mainAxisAlignment: MainAxisAlignment.center)),
                              onPressed: (){_handleSignIn().whenComplete((){Navigator.of(context).pushNamed("/Home");});}
    
                              ,color: Colors.white),
                          ],),
                        new Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          mainAxisSize: MainAxisSize.max,
                          )
    
    
                      ],
                    )
                )
            )
        );
      }
    
    
    }
    

    HomePage 类,该类仅在验证身份验证后才可访问;我家有一个 RaisedButton 在中间,有一个 Text displayName 当前用户的,以及 onPressed() 调用 _signOut() 方法并返回到 SignInage

    final GoogleSignIn _googleSignIn = new GoogleSignIn();
    
    
    class HomePage extends StatefulWidget {
      @override
      _HomePageState createState() => new _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      FirebaseUser _currentUser;
    
      initState() {
        super.initState();
        _myUser();
      }
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Hello:)"),
          ),
          body: new Center(
            child: new RaisedButton(child: new Text(_currentUser.displayName),
                onPressed: (){_signOut().whenComplete((){Navigator.of(context).pushNamed("/SignInPage");});})
          ),
        );
      }
      _signOut() async {
        await FirebaseAuth.instance.signOut();
    
        await _googleSignIn.signOut();
    
        return "Signed out";
      }
    
       _myUser()async {
        FirebaseUser user = await FirebaseAuth.instance.currentUser();
    
        setState((){
          this._currentUser = user;
        });
      }
    
    
    }
    

    问题是:

    1. 签名页 然而,正常情况下,当我成功登录到我的谷歌帐户时,它会冻结而不导航我,因为 displayName was called on Null

    2. 重新启动应用程序并保留以前的身份验证会话时,应用程序会自动以 Home

    3. 在同一个会话中,我单击 升起按钮 签名页 ,我尝试再次登录,我们回到了主要问题,它尝试将我导航到 家 获得。

    这就是我对问题的理解,那么我在这里做错了什么,以及如何设计正确的流程?

    附笔: 我想这样做的原因是因为我想使用 在我的 主页

    更新:

    控制台打印以下内容:

    'package:test/SignInScreen.dart': Failed assertion: line 26: 'user.email != null': is not true.
    

    assert 中的声明 _handleSignIn .

    我也尝试过创建一个预主页,同样的问题也发生了,我不知道现在出了什么问题。

    1 回复  |  直到 9 年前
        1
  •  3
  •   Collin Jackson    9 年前

    FutureBuilder 具有 FirebaseAuth.instance.currentUser() 作为 future builder 方法,如果 hasData AsyncSnapshot Future 完成后,您可以使用 data 的属性 异步快照 获得 FirebaseUser

    _currentUser 在您的 build 方法并返回一个空容器,因为用户信息尚不可用。