在 Flutter 中使用 streamBuilder 时条件不起作用

Condition does not work when using a streamBuilder in Flutter

我正在尝试实现一个显示来自 Firebase 的数据的屏幕,但我希望 streambuilder 检查数据库是否为空,如果它是空的,我希望它显示一条文本“无数据”但如果不是,我希望它显示来自 firebase 的数据。

这是我的代码,但它没有按预期工作,它只是在没有数据时显示一个空白屏幕(当我在数据库中有数据时它工作正常,我只是不想要用户在没有数据时看到空白屏幕)。 你能告诉我这段代码有什么问题吗?实现这个的最佳方法是什么?

@override
  Widget build(BuildContext context) {
    double height = responsive.height(context);
    double width = responsive.width(context);
    var stream = Firestore.instance
        .collection('favoritePost')
        .document(widget.currentUserId)
        .collection('favoritePost')
        .orderBy('timestamp', descending: true)
        .snapshots();
    return Scaffold(
      backgroundColor: kBackgroundColorForAllScreens,
      appBar: PreferredSize(
        preferredSize: Size.fromHeight(responsive.height(context) / 20),
        child: SimpleAppBar(
          label: 'Tus Favoritos',
          witdh: responsive.width(context) / 4.7,
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: Container(
              child: StreamBuilder(
                stream: stream,
                builder: (context, snapshotPost) {
                  if (snapshotPost.hasData) {
                    return ListView.builder(
                      itemExtent: height / 3.3,
                      itemCount: snapshotPost.data.documents.length,
                      itemBuilder: (BuildContext context, int index) {
                        Reviews reviews = Reviews.fromDoc(
                          snapshotPost.data.documents[index],
                        );
                        Provider.of<UserData>(context).reviews = reviews;
                        return ReviewsMenu(
                          reviews: reviews,
                          user: widget.user,
                          currentUserId: widget.currentUserId,
                          showDialogForDelete: true,
                          comingFromFavorite: true,
                        );
                      },
                    );
                  } else {
                    return Center(
                      child: Text('NO DATA'),
                    );
                  }
                },
              ),
            ),
          ),
        ],
      ),
    );
  }

不要在构建方法中初始化流

使用StatefulWidget并在State.initState

中初始化流

// inside, class [...] extends State<[...]>

Stream stream;

@override
void initState() {
  super.initState();
  stream = Firestore.instance
        .collection('favoritePost')
        .document(widget.currentUserId)
        .collection('favoritePost')
        .orderBy('timestamp', descending: true)
        .snapshots();

}

StreamBuilder.builder 中,其中 Snapshot.hasData 检查评论数量是否大于 0

if (snapshot.hasData) {
  if (snapshot.data.documents.length == 0) {
    return Center(child: Text('NO DATA'));
  } 
}

然后像你已经拥有的那样正常使用它

您需要检查 snapshot.data == null:

if (snapshot.data == null || snapshot.data.documents.length == 0) {
  return Center(child: Text('NO DATA'));
}

StreamBuilder 快照在完成查找之前不会有任何数据。因此,最好在任何 Builder(Future 或 Stream)上检查 null。

更新答案 长度部分对我来说不起作用,所以我将它构造成这样,这里只是关键字不同。

stream: stream,
    builder: (BuildContext context, snapshot) {
      if (snapshot.hasData) {
        if (snapshot.data.docs.isEmpty) {
          return new InfoList1();
        } else {
          return new MainHomeScreen();
        }
      } else {
        return new Loading();
      }
    });

并通过调用 State.initState 初始化流,如果有人遇到与我相同的问题。