首页 > 解决方案 > 导航后流生成器未更新

问题描述

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

 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(

标签: flutterauthenticationdartflutter-navigation

解决方案


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

你在说:

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

这就是那个构建方法。一旦建立,你需要说出你接下来想做什么。

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


推荐阅读