Alfonso Angulo
Alfonso Angulo

Reputation: 514

Condition does not work when using a streamBuilder in Flutter

I'm trying to implement a screen that displays data from Firebase but I want the streambuilder to check if the database is empty, if it's empty I want it to show a text saying "no data" but if it's not, I want it to show the data from firebase.

This is the code I have but it does not work as expected, it just shows me a blank screen when there is no data(it works fine when I have data in the database, I just don't want the user to see a blank screen when there is no data). Can you advise what is wrong with this code? what is the best way to implement this?

@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'),
                    );
                  }
                },
              ),
            ),
          ),
        ],
      ),
    );
  }

Upvotes: 3

Views: 3322

Answers (3)

Raza Shabbir
Raza Shabbir

Reputation: 161

Updated answer The length part for me was not working so I structured it something like this, just a keyword difference here.

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();
      }
    });

And initialized the stream by calling State.initState, if someone has the same problem as me.

Upvotes: 0

Mensch
Mensch

Reputation: 700

Dont initialize streams in build method

Use StatefulWidget and initialize the stream in 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();

}

inside StreamBuilder.builder where Snapshot.hasData check if the number of reviews are greater then 0

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

then use it normally as you already have

Upvotes: 8

Scott Godfrey
Scott Godfrey

Reputation: 671

You'll need to check if snapshot.data == null:

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

StreamBuilder snapshot will not have any data until it has completed the lookup. So, it's always best to check for null on any Builder (Future or Stream).

Upvotes: 1

Related Questions