收听对Firebase集合的更改以及其中的所有文档

时间:2019-12-17 03:18:30

标签: flutter dart google-cloud-firestore stream-builder

我正在构建一个包含讨论线程的应用程序。每个线程都有答复的子集合,每个答复都有这样的反应图。因此,如果经过JSON化,则每个线程的子集合将如下所示:

{
  'replyDocument1': { 
    'authorName': 'Steve Dave', 
    'text': 'this is a reply', 
    'reactions': {'?': ['userid1', 'userid2']}
  },
  ...
}

我正在尝试使用流/接收器设置来侦听“答复”子集合中的更改。即:只要有人向子集合中的任何“答复”​​添加“反应”,就重建“答复” ListView。

这是我到目前为止所掌握的。模型和RepliesApi类没有做任何令人兴奋的事情,因此我将它们省略了。

class RepliesBloc {
  final String threadId;
  RepliesApi _api;
  final _controller = StreamController<List<Reply>>.broadcast();
  Stream<List<Reply>> get stream =>
      _controller.stream.asBroadcastStream();
  StreamSink<List<Reply>> get sink => _controller.sink;

  RepliesBloc(this.threadId) {
    this._api = RepliesApi(this.threadId);
    this
        ._api
        .collectionReference
        .getDocuments()
        .asStream()
        .listen(_repliesUpdated);
    this._api.collectionReference.snapshots().listen(_repliesUpdated);
  }

  void _repliesUpdated(QuerySnapshot querySnapshot) {
    List<Reply> replies = _api.fromQuerySnapshot(querySnapshot);
    this.sink.add(replies);
  }

  void dispose() {
    _controller.close();
  }
}
class ThreadReplyList extends StatefulWidget {
  ThreadReplyList(this.threadId, {Key key}) : super(key: key);
  final String threadId;

  @override
  _ThreadReplyListState createState() => _ThreadReplyListState();
}

class _ThreadReplyListState extends State<ThreadReplyList> {
  RepliesBloc _bloc;

  @override
  void initState() {
    super.initState();
    this._bloc = RepliesBloc(this.widget.threadId);
  }

  @override
  Widget build(BuildContext context) {
    dev.log('starting ThreadReplyList.build', name: "ThreadReplyList.build");

    return StreamBuilder(
        stream: this._bloc.stream,
        builder: (context, snapshot) {
          return ListView.separated(
            itemCount: snapshot.data.length,
            itemBuilder: (BuildContext context, int index) {
              return ThreadReply(snapshot.data[index]);
            },
            separatorBuilder: (BuildContext context, int index) {
              return SizedBox.shrink();
            },
          );
        });
  }
}

这样可以很好地加载初始数据,如果我更改了集合,例如:添加或删除Reply,则ListView会重建。但是,如果我修改了一个Reply,例如:在单个Reply上更新reactions地图,则什么也没有发生。

我已经看到了将侦听器添加到QuerySnapshot中的每个文档的解决方案,但是我不清楚如何在此处实现。

0 个答案:

没有答案