Provider 使用 Streams 公开不正确的值

Provider exposes incorrect values with Streams

我正在使用 Provider with 将一些参数暴露给树深处的小部件。小部件是从 Streambuilder 构建的,即 Firebase 文档

但是,Provider 似乎没有公开正确的值

我的代码的一个非常简化的版本:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:provider/provider.dart';

class Parameters {
  Parameters(this.documentId);
  final String documentId;
}

class Widget1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
        stream: mystream, //Query the Firebase for a bunch of Documents
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Text('Error processing data feed');
          }
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              {
                return CircularProgressIndicator();
              }
              break;
            default:
              {
                var _messages = snapshot.data.documents;

                return ListView.builder(
                    itemCount: _messages.length,
                    itemBuilder: (context, index) {
                      return Provider<Parameters>(
                          builder: (context) =>
                              Parameters(_messages[index].documentID),
                          child: AnotherWidget());
                    });
              }
          }
        });
  }
}

class AnotherWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Parameters param = Provider.of<Parameters>(context);
    return Text(param.documentId);
  }
}

第一次构建小部件时,这工作得很好。但是,当插入新文档时,AnotherWidget 显示前一个文档的文档 ID

如何在更新流时获取正确的文档 ID?

Note: I am aware I can simply pass the document as a parameter. However I need the parameter deep down the widget tree of AnotherWidget

看起来这正是引入 ProxyProvider 的原因

https://pub.dev/documentation/provider/latest/provider/ProxyProvider-class.html 引用重要提示:

As opposed to the builder parameter of Provider, builder may be called more than once. It will be called once when the widget is mounted, then once whenever any of the InheritedWidget which ProxyProvider depends emits an update

通过使用包含 ProxyProvider 的 MultiProvider 包装 AnotherWidget(如下所示)解决了问题

child: MultiProvider(
                        providers: [
                            Provider.value(value: _messages[index].documentID),
                            ProxyProvider<String, Parameters>(
                              builder: (context, documentId, parameters) => Parameters(documentId),
                            ),
                          ],
                          child: AnotherWidget()));