Не работает условие при использовании streamBuilder во 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'),
                    );
                  }
                },
              ),
            ),
          ),
        ],
      ),
    );
  }

person Alfonso Angulo    schedule 07.08.2020    source источник


Ответы (3)


Не инициализировать потоки в методе сборки

Используйте 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'));
  } 
}

затем используйте его как обычно, так как у вас уже есть

person DelphiX    schedule 07.08.2020
comment
Спасибо, братан, все работает нормально, но я получаю эту ошибку в консоли. «Документы» геттера были вызваны с нулевым значением. Получатель: null Пытался позвонить: документы - person Alfonso Angulo; 07.08.2020

Вам нужно будет проверить, если snapshot.data == null:

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

В моментальном снимке StreamBuilder не будет данных, пока он не завершит поиск. Итак, всегда лучше проверять значение null на любом Builder (Future или Stream).

person Scott Godfrey    schedule 10.08.2020

Обновленный ответ. Часть длины для меня не работала, поэтому я структурировал ее примерно так, просто разница в ключевых словах.

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, если у кого-то такая же проблема, как у меня.

person Raza Shabbir    schedule 25.03.2021