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

Posted

技术标签:

【中文标题】在 Flutter 中使用 streamBuilder 时条件不起作用【英文标题】:Condition does not work when using a streamBuilder in Flutter 【发布时间】:2020-11-27 07:03:00 【问题描述】:

我正在尝试实现一个显示来自 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'),
                    );
                  
                ,
              ),
            ),
          ),
        ],
      ),
    );
  

【问题讨论】:

【参考方案1】:

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

使用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'));
   

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

【讨论】:

谢谢,兄弟,它工作正常,但是我在控制台中收到此错误“在 null 上调用了 getter 'documents'。接收方:null 尝试调用:documents”【参考方案2】:

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

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

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

【讨论】:

【参考方案3】:

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

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 来初始化流。

【讨论】:

以上是关于在 Flutter 中使用 streamBuilder 时条件不起作用的主要内容,如果未能解决你的问题,请参考以下文章

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

FirebaseStorage + Flutter,streamBuilder?

如何在flutter中从streambuilder导航到其他页面?

如何在 Flutter 中使用 Firestone 的 streambuilder 获取嵌套文档?

如何在 Firebase + Firestore + Flutter 中使用 StreamBuilder 将所有子集合数据获取到 Widget

Flutter:如何为 StreamBuilder 制作 http 流