【问题标题】:stream builder is not updating after navigation导航后流生成器未更新
【发布时间】:2020-08-10 10:19:37
【问题描述】:

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

 return StreamBuilder<User>(
        stream: AuthService().user,
        builder: (context, snapshot) {
          if (snapshot.hasData)
            return SectionWrapper();
          else
            return Authentication();
        });

这是我正在使用的流

 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;
  }

在部分包装器中,有 2 个按钮导航到应用程序的两个不同部分,当我在其中一个部分中使用注销方法时,流构建器不会更新,它需要刷新才能更新状态。

我还尝试在部分包装器中放置一个按钮以退出,它可以在我导航到其中一个部分之前工作并更新 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();
              }),
        ],
      ),

我也尝试将流提供程序与消费者一起使用,但我遇到了同样的问题。

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

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<User>(context);
    return user == null ? Authentication() : SectionWrapper();
  }
}

我使用流提供程序包装了材质应用程序。

MultiProvider(
      providers: [
        StreamProvider<User>.value(value: AuthService().user),
//other providers
      ],
      child: MaterialApp(

【问题讨论】:

  • 您应该为此使用流提供程序。
  • 我试过了,结果还是一样
  • Streambuilder 有更多样板。您可能需要检查错误和连接状态,例如this example from the docs。我并不惊讶这不起作用。
  • StreamProvider 将 100% 工作。我也在做同样的事情。您是否将提供程序放在小部件树中足够高的位置?您可以与 streamProvider 分享您的代码吗?并指出你把提供者放在哪里?
  • 我编辑了问题并分享了代码,我认为它已经足够高了,除非我应该在导航时传递一些数据。请看一下

标签: flutter authentication dart flutter-navigation


【解决方案1】:

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

你是说:

  • 如果用户已登录,则构建 sectionWrapper 小部件
  • 如果用户未登录构建身份验证小部件。

这就是构建方法。构建完成后,您需要说出下一步要做什么。

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

【讨论】:

  • 它确实有效!我已经挣扎了大约 3 周,你帮助了我。非常感谢,我真的很感激!
  • 太棒了!我很高兴能帮上忙,谢谢你的消息。也请点赞:)
  • 当我尝试了您的解决方案时,它工作正常,但是当我再次使用另一个用户登录时,我又回到了我注销的位置,问题是当我进行操作时,所有操作尽管用户 ID 不同,但在我使用导航器或其他工具刷新页面以再次获取数据之前,前一个用户会发生这种情况,所以在退出时有什么方法可以转到部分包装器,以便当我重新登录时,部分包装器发生,当我导航到某个部分时,再次获取数据
  • 我的朋友,这似乎是一个业务逻辑问题。如果不查看其余代码,很难更精确,但基本上:提供者将在用户更改时重建您所在的页面。因此,在该页面的顶部,使用您的构建方法,您想要执行逻辑,即如果用户为空,则转到身份验证。您可能还想重新审视使​​用 Navigator 在屏幕之间导航的方式。
  • 最终,这不是同一个问题。您应该为此提出另一个问题
猜你喜欢
  • 1970-01-01
  • 2012-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多