Flutter Provider:提供 2 个流,一个依赖另一个

Posted

技术标签:

【中文标题】Flutter Provider:提供 2 个流,一个依赖另一个【英文标题】:Flutter Provider: Provide 2 streams with one dependent on the other 【发布时间】:2020-04-21 11:20:06 【问题描述】:

我正在使用提供程序包。在小部件树的根目录中,我有一个 multiprovider:

Widget build(BuildContext context) 
    return MultiProvider(
      providers: [
        StreamProvider<FirebaseUser>.value(
            value: FirebaseConnection.getAuthenticationStream()),
        StreamProvider<User>.value(
            value: FirebaseConnection.getUserStream(uid: ???))
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        initialRoute: LoginScreen.id,
        onGenerateRoute: RouteGenerator.generateRoute,
      ),
    );
  

第一个 StreamProvider 提供来自 firebase_auth 的登录用户。 第二个 StreamProvider 应该为该用户提供附加信息(存储在 users 集合中)。 问题是要获得第二个流,我需要第一个流提供的 FirebaseUser 的 uid,但我不知道如何访问它。

嵌套 StreamProviders 不起作用,因为在第二个流中我只能访问构建方法的(错误)上下文(对于 Provider.of(context))

【问题讨论】:

FirebaseConnection 是您创建的课程吗?我在 firebase 文档中找不到它。 是的,它是包含返回流的函数的类 您希望从第一个流中获得多少响应?您是否仅将其用于第二个流? 检查用户是否登录并让他的 uid 为第二个流提供它是我需要第一个流的唯一原因(当没有用户登录时,第一个流返回 null)。如果我可以让第二个流在没有用户登录时也返回 null,我就不需要第一个流。 那么也许不是将第一个流提供给它自己的提供者,而是单独创建流,侦听第一个事件,并使用事件数据创建第二个流。将所有这些放在一个异步方法中,该方法异步返回流并从FutureBuilder 调用它。一旦 future 完成并返回流,将其传递给提供者。 【参考方案1】:

解决方案是将第二个流 (loggedInUserStream) 保存在状态中,并在第一个流 (authenticationStream) 发出新值(通过侦听)时更改它,如下面的代码所示:

class _FloatState extends State<Float> 
  StreamSubscription<FirebaseUser> authenticationStreamSubscription;
  Stream<User> loggedInUserStream;

  StreamSubscription<FirebaseUser> setLoggedInUserStream() 
    authenticationStreamSubscription =
        FirebaseConnection.getAuthenticationStream().listen((firebaseUser) 
      loggedInUserStream =
          FirebaseConnection.getUserStream(uid: firebaseUser?.uid);
    );
  

  @override
  void initState() 
    super.initState();
    authenticationStreamSubscription = setLoggedInUserStream();
  

  @override
  void dispose() 
    super.dispose();
    authenticationStreamSubscription.cancel();
  

  @override
  Widget build(BuildContext context) 
    return StreamProvider<User>.value(
      value: loggedInUserStream,
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        initialRoute: LoginScreen.id,
        onGenerateRoute: RouteGenerator.generateRoute,
      ),
    );
  

我只需要第一个流 (authenticationStream) 来获取第二个流 (loggedInUserStream),所以我没有将它提供给下面的小部件。

【讨论】:

以上是关于Flutter Provider:提供 2 个流,一个依赖另一个的主要内容,如果未能解决你的问题,请参考以下文章

使用 Provider 向整个 Flutter 模块全局提供 BLoC

Flutter BLoC:组合超过 9 个流

如何使用 Provider 实现 Flutter 本地化?

使用 Provider 工具时出现 Flutter 错误

Flutter 等待 Provider 准备好在 multiprovider 中

Flutter 中的 Bloc Provider 和 Normal Provider 有啥区别?