Flutter 导航后,流生成器未更新

Flutter 导航后,流生成器未更新,flutter,authentication,dart,flutter-navigation,Flutter,Authentication,Dart,Flutter Navigation,我正在使用流生成器来检测用户是否登录 return StreamBuilder<User>( stream: AuthService().user, builder: (context, snapshot) { if (snapshot.hasData) return SectionWrapper(); else return Authentication();

我正在使用流生成器来检测用户是否登录

 return StreamBuilder<User>(
        stream: AuthService().user,
        builder: (context, snapshot) {
          if (snapshot.hasData)
            return SectionWrapper();
          else
            return Authentication();
        });
返回StreamBuilder(
流:AuthService()。用户,
生成器:(上下文,快照){
if(snapshot.hasData)
返回SectionWrapper();
其他的
返回身份验证();
});
这就是我正在使用的流

 Stream<User> get user {
    return _auth.onAuthStateChanged.map(_userFromFirebaseUser);
  }
  //create user object based on firebase user
  User _userFromFirebaseUser(FirebaseUser user) {
    return user != null ? User(uid: user.uid, email: user.email) : null;
  }
流获取用户{
返回_auth.onAuthStateChanged.map(_userFromFirebaseUser);
}
//基于firebase用户创建用户对象
用户\u userFromFirebaseUser(FirebaseUser用户){
返回用户!=null?用户(uid:user.uid,email:user.email):null;
}
在分区包装器中,有两个按钮导航到应用程序的两个不同分区,当我在其中一个分区中使用注销方法时,流生成器没有更新,需要刷新以更新状态

我还尝试在分区包装器中放置一个按钮以注销,在导航到其中一个分区之前,它可以工作并更新UI

这是sectionWrapper()小部件树

Column(
        children: <Widget>[
          CupertinoButton(
              child: Text('Donation & Selling Section'),
              onPressed: () {
                Navigator.pushReplacementNamed(
                    context, Section1.routeName,
                    arguments: user);
              }),
          CupertinoButton(
              child: Text('Bookstores Section'),
              onPressed: () {
                Navigator.pushReplacementNamed(
                    context, Section2.routeName);
              }),
          
          //works before navigation, does not work after navigation back here
          CupertinoButton(
              child: Text('Sign out'),
              onPressed: () async {
                await AuthService().signOut();
              }),
        ],
      ),
列(
儿童:[
丘比特纽扣(
儿童:文本(“捐赠和销售部分”),
已按下:(){
Navigator.pushReplacementNamed(
上下文,第1.1节路由名称,
参数:用户);
}),
丘比特纽扣(
子项:文本(“书店部分”),
已按下:(){
Navigator.pushReplacementNamed(
上下文,第2节路由名称);
}),
//导航前工作,导航后不工作回到这里
丘比特纽扣(
子项:文本(“注销”),
onPressed:()异步{
等待AuthService().注销();
}),
],
),
我还尝试将流提供程序与消费者一起使用,结果遇到了相同的问题

   class Wrapper extends StatelessWidget {
  static const String routeName = '/';

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<User>(context);
    return user == null ? Authentication() : SectionWrapper();
  }
}
类包装扩展了无状态小部件{
静态常量字符串routeName='/';
@凌驾
小部件构建(构建上下文){
最终用户=提供者(上下文);
return user==null?身份验证():SectionWrapper();
}
}
我用流提供商包装了material应用程序

MultiProvider(
      providers: [
        StreamProvider<User>.value(value: AuthService().user),
//other providers
      ],
      child: MaterialApp(
MultiProvider(
供应商:[
StreamProvider.value(值:AuthService().user),
//其他提供者
],
孩子:MaterialApp(

您的条件未在子页面中测试。您应该在sectionWrapper()页面中调用Provider.of

你是说:

  • 如果用户已登录,则生成sectionWrapper小部件
  • 如果用户未登录构建身份验证小部件
这就是构建方法。一旦构建完成,您需要说明下一步要做什么

例如。
在下一个屏幕上,在小部件树的上方,像您一样设置provider.of。然后,如果值发生变化,provider将强制重新生成该屏幕的构建方法。

您可能应该为此使用流提供程序。我尝试了,并不断得到相同的结果streambuilder有更多的样板文件。您可能需要检查错误和连接状态之类的。我并不惊讶这不起作用。StreamProvider将100%起作用。我也在做同样的事情。你是否将提供程序放在小部件树中足够高的位置?你能与StreamProvider共享你的代码吗?并指出你将提供程序放在哪里?我编辑了问题并共享了代码,我认为它足够高,除非我同意当导航时,我会传递一些数据。请看一看,它确实起作用了!我已经挣扎了大约3周,你帮助了我。非常感谢你,我真的很感激!太棒了!我很高兴我能帮上忙,谢谢你的留言。也请投票:)当我尝试您的解决方案时,效果很好,但是当我再次与另一个用户登录时,我回到了我注销的位置,问题是当我执行操作时,所有操作都会与前一个用户一起执行,尽管用户id不同,直到我使用navigator或其他工具刷新页面以再次获取数据为止,那么有什么办法吗注销时进行节包装,这样当我重新登录时,会出现节包装,当我导航到某个节时,会重新获取数据,这似乎是一个业务逻辑问题,我的朋友。如果不查看您的其余代码,很难更准确地说,但基本上:当用户更改时,提供程序将重建您所在的页面。因此t在该页面的顶部,使用构建方法,您希望执行逻辑,即如果用户为null,则转到身份验证。您可能还希望重新了解如何使用Navigator在屏幕之间导航。最终,这不是同一个问题。您应该为此问另一个问题