Firebase Streambuilder在导航后未更改登录状态

Firebase Streambuilder在导航后未更改登录状态,firebase,flutter,firebase-authentication,Firebase,Flutter,Firebase Authentication,在这里,我试图实现Firebase登录和注册系统。我正在尝试根据用户登录与否更改屏幕 基本上,当用户登录时,我想显示提要屏幕,当用户未登录时,我想显示登录屏幕。若我在登录屏幕中登录,那个么工作正常,所以我并没有在这里添加那个代码。但当我从登录屏幕导航到注册屏幕时,问题就出现了,即使我成功注册,它也不会显示给我提要屏幕。当我热重新加载时,它显示给我饲料屏幕 此外,我还确保它达到了我在控制台中通过打印更改屏幕的位置 注意:我知道我可以使用这个函数在登录屏幕和注册屏幕之间进行切换,所以我不需要导航器,

在这里,我试图实现Firebase登录和注册系统。我正在尝试根据用户登录与否更改屏幕

基本上,当用户登录时,我想显示提要屏幕,当用户未登录时,我想显示登录屏幕。若我在登录屏幕中登录,那个么工作正常,所以我并没有在这里添加那个代码。但当我从登录屏幕导航到注册屏幕时,问题就出现了,即使我成功注册,它也不会显示给我提要屏幕。当我热重新加载时,它显示给我饲料屏幕

此外,我还确保它达到了我在控制台中通过打印更改屏幕的位置

注意:我知道我可以使用这个函数在登录屏幕和注册屏幕之间进行切换,所以我不需要导航器,它同样适用于我。但我想知道为什么在使用navigator导航后它不起作用

class DeleteWidget extends StatefulWidget {
  @override
  _DeleteWidgetState createState() => _DeleteWidgetState();
}

class _DeleteWidgetState extends State<DeleteWidget> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StreamBuilder<FirebaseUser>(
          stream: FirebaseAuth.instance.onAuthStateChanged,
          builder: (BuildContext context, snapshot) {
            print(snapshot.hasData);
            print(snapshot.connectionState);
            if (ConnectionState.active == snapshot.connectionState) {
              print("object 1");
              if (snapshot.hasData) {
                print("object 2");
                return Feed();
              } else {
                print("object 3");
                return LoginScreen();
              }
            } else {
              return LoginScreen();
            }
          }),
    );
  }
}

class LoginScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          child: RaisedButton(
            child: Text("login"),
            onPressed: () async {
              Navigator.push(
                  context, MaterialPageRoute(builder: (context) => SignUp()));
            },
          ),
        ),
      ),
    );
  }
}

class SignUp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          child: RaisedButton(
            child: Text("Sign up"),
            onPressed: () async {
              await FirebaseAuth.instance.signInAnonymously();
            },
          ),
        ),
      ),
    );
  }
}

class Feed extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          child: RaisedButton(
            child: Text("feed"),
            onPressed: () async {
              await FirebaseAuth.instance.signOut();
            },
          ),
        ),
      ),
    );
  }
}
类DeleteWidget扩展StatefulWidget{
@凌驾
_DeleteWidgetState createState()=>\u DeleteWidgetState();
}
类_DeleteWidgetState扩展状态{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主页:StreamBuilder(
流:FirebaseAuth.instance.onAuthStateChanged,
生成器:(BuildContext上下文,快照){
打印(snapshot.hasData);
打印(快照.连接状态);
if(ConnectionState.active==snapshot.ConnectionState){
打印(“对象1”);
if(snapshot.hasData){
打印(“对象2”);
返回馈送();
}否则{
打印(“对象3”);
返回LoginScreen();
}
}否则{
返回LoginScreen();
}
}),
);
}
}
类LoginScreen扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子:容器(
孩子:升起按钮(
子项:文本(“登录”),
onPressed:()异步{
导航器。推(
context,materialpage(builder:(context)=>SignUp());
},
),
),
),
);
}
}
类注册扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子:容器(
孩子:升起按钮(
孩子:文本(“注册”),
onPressed:()异步{
等待FirebaseAuth.instance.signinanoymously();
},
),
),
),
);
}
}
类提要扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
子:容器(
孩子:升起按钮(
子:文本(“提要”),
onPressed:()异步{
等待FirebaseAuth.instance.signOut();
},
),
),
),
);
}
}
您可以使用来侦听用户是否登录,并使用包装器将用户引导到正确的屏幕。如果用户在任何阶段注销,他们将自动重定向到登录屏幕

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

User _userFromFirebaseUser(FirebaseUser user) {
    return user != null ? User(uid: user.uid) : null;
  }

  @override
  Widget build(BuildContext context) {
    return StreamProvider<User>.value(
      value: FirebaseAuth.instance.onAuthStateChanged.map(_userFromFirebaseUser),
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
用户\u userFromFirebaseUser(FirebaseUser用户){
返回用户!=null?用户(uid:user.uid):null;
}
@凌驾
小部件构建(构建上下文){
返回StreamProvider.value(
值:FirebaseAuth.instance.onAuthStateChanged.map(\u userFromFirebaseUser),
孩子:MaterialApp(
主:Wrapper(),
),
);
}
}
包装纸

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    final user = Provider.of<User>(context);
    if(user == null) {
      return LoginScreen();
    } else {
      return Feed();
    }
    }
  }
类包装扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
最终用户=提供者(上下文);
if(user==null){
返回LoginScreen();
}否则{
返回馈送();
}
}
}
您可以使用来侦听用户是否登录,并使用包装器将用户引导到正确的屏幕。如果用户在任何阶段注销,他们将自动重定向到登录屏幕

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

User _userFromFirebaseUser(FirebaseUser user) {
    return user != null ? User(uid: user.uid) : null;
  }

  @override
  Widget build(BuildContext context) {
    return StreamProvider<User>.value(
      value: FirebaseAuth.instance.onAuthStateChanged.map(_userFromFirebaseUser),
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
用户\u userFromFirebaseUser(FirebaseUser用户){
返回用户!=null?用户(uid:user.uid):null;
}
@凌驾
小部件构建(构建上下文){
返回StreamProvider.value(
值:FirebaseAuth.instance.onAuthStateChanged.map(\u userFromFirebaseUser),
孩子:MaterialApp(
主:Wrapper(),
),
);
}
}
包装纸

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    final user = Provider.of<User>(context);
    if(user == null) {
      return LoginScreen();
    } else {
      return Feed();
    }
    }
  }
类包装扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
最终用户=提供者(上下文);
if(user==null){
返回LoginScreen();
}否则{
返回馈送();
}
}
}

感谢您的回复。但我的问题是,为什么在使用navigator之后,它不起作用。我知道还有很多其他选项可以选择。我相信这是因为你需要
设置状态
-页面不知道它需要重新绘制。如果我在登录屏幕中登录,它会更改屏幕,但在导航到注册屏幕然后登录时,它不会更改屏幕。或者我必须调用setState,因为如果我在StreamBuilder中设置state,那么它会抛出错误。正在生成时调用setState。感谢您的回复。但我的问题是,为什么在使用navigator之后,它不起作用。我知道还有很多其他选项可以选择。我相信这是因为你需要
设置状态
-页面不知道它需要重新绘制。如果我在登录屏幕中登录,它会更改屏幕,但在导航到注册屏幕然后登录时,它不会更改屏幕。或者我必须调用setState,因为如果我在StreamBuilder中设置state,那么它会抛出错误。生成时调用了setState。请检查您的代码。您的注册小部件正在登录,您的登录小部件正在推送到注册屏幕。复习你的c