Mary X
Mary X

Reputation: 310

How to make StreamBuilder stop listening for events

I am using a StreamBuilder to access the contents of my Firestore database and create a list of List Tiles for such content. My problem is that whenever I click on a List Tile, it's like my StreamBuilder method gets called again and doubles the amount of List Tiles that I need in my list (since I am using the List.add() method).

How do I make StreamBuilders stop "re-building" or "listening"? I'm fairly new to Dart so I'm not sure how to approach this.

Here is the code that keeps getting repeated. (I have censored some information in places that contain "..." for the purpose of this post):

Widget showContent(BuildContext context) {
    var topics = new List();
    var messages = new List();
    var dates = new List();
    List<Widget> content = new List<Widget>();

    return new StreamBuilder<QuerySnapshot>(
        stream: Firestore.instance.collection("collection-id").snapshots(),
        builder: (context, snap) {
          //just add this line
          if (snap.data == null) return CircularProgressIndicator();

          for (int i = 0; i < snap.data.documents.length; i++) {
            topics.add(...);
            messages.add(snap.data.documents[i]["message"].toString());
            dates.add(...);
          }

          for (var i = 0; i < topics.length; i++) {
            content.add(new Container(
                child: new ListTile(
                  leading: Icon(Icons.events, color: Colors.black, size: 30,),
                  title: Text(topics[i].toString()),
                  subtitle: Text(messages[i].toString()),
                  onTap: () {
                    Navigator.push(context,
                      MaterialPageRoute(builder: (context) => ReadContent(topics[i], messages[i],dates[i])),
                    );
                  },
                ),
                decoration: new BoxDecoration(border: new Border(bottom: new BorderSide()))));
          }//for
          return new Column(children: content);
        });//StreamBuilder
}//showContent()

This is a snippet from Stateful widget where showContent() is called:

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('App'),
      ),
      body: Center(
        child: new Container(
          child: new SingleChildScrollView(
            child: new Column(
              children: <Widget>[

                  showContent(context),
              ],
            ),
          ),
        ),
      ),
 );//Scaffold
}

Upvotes: 0

Views: 957

Answers (1)

Michel Feinstein
Michel Feinstein

Reputation: 14266

You didn't post any code so I will have to guess how your code works.

I assume you are using your Firebase Stream right inside the StreamBuilder.stream, so every time build is called this Firebase call is being invoked again and again.

build() functions are supposed to have no side effects, you should call Firebase on initState() and save that call as a Future or a Stream and then use that variable on your build() function's StreamBuilder. This way the Future/Stream is only created once.

Again, you didn't post any code, so I am assuming a lot here.

Upvotes: 1

Related Questions