cloud_firestore文档中的此示例使用StreamBuilderConnectionStateAsyncSnapshot来处理处于不同状态的流。通过ConnectionState而不是StreamProvider访问流时,是否有类似的方法来管理StreamBuilder?避免它在实际上从Firestore获得文档之前短时间内返回null的最佳方法是什么?

这是带有StreamBuilder的cloud_firestore文档中的示例:

    class BookList extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return StreamBuilder<QuerySnapshot>(
          stream: Firestore.instance.collection('books').snapshots(),
          builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
            if (snapshot.hasError)
              return new Text('Error: ${snapshot.error}');
            switch (snapshot.connectionState) {
              case ConnectionState.waiting: return new Text('Loading...');
              default:
                return new ListView(
                  children: snapshot.data.documents.map((DocumentSnapshot document) {
                    return new ListTile(
                      title: new Text(document['title']),
                      subtitle: new Text(document['author']),
                    );
                  }).toList(),
                );
            }
          },
        );
      }
    }


我有一个基本的流:
    List<AuditMark> _auditMarksFromSnapshot(QuerySnapshot qs) {
      return qs.documents.map((DocumentSnapshot ds) {
        return AuditMark.fromSnapshot(ds);
      }).toList();
    }

    Stream<List<AuditMark>> get auditMarks {
      return Firestore.instance
          .collection('_auditMarks')
          .snapshots()
          .map(_auditMarksFromSnapshot);
    }


这可以通过StreamProvider访问(这里省略了其他提供程序):
    void main() async {
      runApp(MultiProvider(
        providers: [
          StreamProvider<List<AuditMark>>(
              create: (_) => DatabaseService().auditMarks, ),
        ],
        child: MyApp(),
      ));
    }


我曾尝试以某种方式将QuerySnapshot转换为AsyncSnapshot<QuerySnapshot>,但可能会出错。
当然可以像这样给StreamProvider一些initialData-但这很麻烦,容易出错并且可能很昂贵:
    initialData: <AuditMark>[
      AuditMark.fromSnapshot(await Firestore.instance
          .collection('_auditMarks')
          .orderBy('value')
          .getDocuments()
          .then((value) => value.documents.first))


...但是我希望有一种更聪明的方法来管理连接状态,并避免它在可以发出文档之前返回null?

最佳答案

我一直在处理这个问题,不想声明initialData来绕过此问题。

我所做的是创建一个StreamBuilder作为StreamProvider 的子代。
这样我就可以在 StreamProvider中使用StreamBuilder snapshot.connectionState属性。

这是代码:

    return StreamProvider<List<AuditMark>>.value(
        value: DatabaseService().auditMarks,
        child: StreamBuilder<List<AuditMark>>(
                stream: DatabaseService().auditMarks,
                builder: (context, snapshot) {
                    if (!snapshot.hasError) {
                        switch (snapshot.connectionState) {
                            case ConnectionState.none: // if no connection
                                return new Text(
                                    "Offline!",
                                    style: TextStyle(fontSize: 24, color: Colors.red),
                                    textAlign: TextAlign.center,
                                );
                            case ConnectionState.waiting
                                // while waiting the data, this is where you'll avoid NULL
                                return Center(child: CircularProgressIndicator());
                            default:
                                return ListView.builder(
                                    // in my case I was getting NULL for itemCount
                                    itemCount: logs.length,
                                    itemBuilder: (context, index) {
                                        return LogsTile(log: logs[index]);
                                    },
                                );
                        }
                    }
                    else {
                        return new Text(
                            "Error: ${snapshot.error}",
                            style: TextStyle(fontSize: 17, color: Colors.red),
                            textAlign: TextAlign.center,
                        );
                    }
                }
        )
    );

关于flutter - 如何使用StreamProvider检查Firestore快照流的ConnectionState?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61422082/

10-09 04:45