flutterdartstream-builderflutter-slivercustomscrollview

Wrapping a CustomScrollView and a Sliverlist with a Streambuilder throws exception


I am trying to listen for real-time documents from Firebase firestore using Streambuilder while displaying the retrieved data in a CustomScrollView and a SliverListbut when I do so the list breaks and the screen remains blank.

I tried a FutureBuilder and it worked, but it doesn't satisfy my requirements.

This is the code I wrote for the streambuilder:

Widget sliverList() {
  return CustomScrollView(
    slivers: <Widget>[
      SliverAppBar(
        backgroundColor: Colors.transparent,
        expandedHeight: 220.0,
        flexibleSpace: FlexibleSpaceBar(
          collapseMode: CollapseMode.parallax,
          background: Column(
            children: [Daily(), AddPost()],
          ),
        ),
      ),
      StreamBuilder<QuerySnapshot>(
          stream: feedServices.listenToFeedinStream(),
          builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
            return SliverFixedExtentList(
              itemExtent: 500,
              delegate: SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  if (snapshot.hasData) {
                    Post post = Post.fromMap(snapshot.data.docs[index].data());
                    return Column(
                      children: [
                        FeedItem(
                          thread: post,
                        ),
                        seperator()
                      ],
                    );
                  } else if (!snapshot.hasData) {
                    return Text('no data');
                  } else if (snapshot.hasError) {
                    return Text('has err');
                  } else {
                    return Text('not specified');
                  }
                },
                childCount: snapshot.data.docs.length,
              ),
            );
          })
    ],
  );
}

Exceptions caught:

flutter: The following NoSuchMethodError was thrown building StreamBuilder<QuerySnapshot>(dirty, state:
flutter: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#da6d3):
flutter: The getter 'docs' was called on null.
flutter: Receiver: null
flutter: Tried calling: docs

Solution

  • You should only pass Sliver Widgets to slivers list. StreamBuilder isn't a Sliver, so you can wrap whole CustomScrollView with StreamBuilder.

    Widget sliverList() {
      return StreamBuilder<QuerySnapshot>(
        stream: feedServices.listenToFeedinStream(),
        builder: (context, snapshot) {
          return CustomScrollView(
            slivers: <Widget>[
              SliverAppBar(
                backgroundColor: Colors.transparent,
                expandedHeight: 220.0,
                flexibleSpace: FlexibleSpaceBar(
                  collapseMode: CollapseMode.parallax,
                  background: Column(
                    children: [Daily(), AddPost()],
                  ),
                ),
              ),
              SliverFixedExtentList(
                  itemExtent: 500,
                  delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                      if (snapshot.hasData) {
                        Post post = Post.fromMap(snapshot.data.docs[index].data());
                        return Column(
                          children: [
                            FeedItem(
                              thread: post,
                            ),
                            seperator()
                          ],
                        );
                      } else if (!snapshot.hasData) {
                        return Text('no data');
                      } else if (snapshot.hasError) {
                        return Text('has err');
                      } else {
                        return Text('not specified');
                      }
                    },
                    childCount: snapshot.data.docs.length,
                  ),
                )
            ],
          );
        },
      );
    }