Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Streambuilder rebuilds constantly

I have a stream builder listening to Firestore, and it kinda works. The main issue is that the streambuilder keeps rebuilding (if it doesn't cost me extra reads then no worries, but if it does then it's a problem which I'm assuming it does). When the main page first builds, when I segue to another page it builds again, and when I pop back to the main page it rebuilds for a third time.

Code:

class _RequestsListState extends State<RequestsList> with AutomaticKeepAliveClientMixin {
  final Map<String, List<Post>> posts = {};
  final List<String> postsUserIDs = [];

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);

    print('RequestsList');
    User cUser = InheritedUser.of(context).user;

    return StreamBuilder<List<Post>>(
        initialData: cUser.posts,
        stream: APIs().posts.auPostsStream(cUserID: cUser.userID),
        builder: (context, snap) {
          if (snap.hasError) {
            print('AUPostsList.dart StreamBuilder Error: ${snap.error}');
            return null;
          } else {

            print('POSTS LENGTH');
            print(snap.connectionState);
            print(cUser.posts.length);

            this.posts.clear();
            this.postsUserIDs.clear();

            snap.data.forEach((post) {
              if (this.posts[post.user.documentID] == null) {
                this.posts[post.user.documentID] = [post];
              } else {
                this.posts[post.user.documentID].add(post);
              }

              if (!this.postsUserIDs.contains(post.user.documentID)) {
                this.postsUserIDs.add(post.user.documentID);
              }
            });

            return ListView.separated(
                controller: widget.scrollController,
                physics: BouncingScrollPhysics(),
                shrinkWrap: true,
                padding: EdgeInsets.only(top: 0.0),
                itemBuilder: (context, index) => RequestItem(posts: this.posts[this.postsUserIDs[index]]),
                separatorBuilder: (context, index) => Container(),
                itemCount: this.postsUserIDs.length);
          }
        });
  }
}

And secondly, the when I segue to the second page, the array gets emptied. I'm not clearing it anywhere so I'm not sure why it empties the array after tapping an item...

Log:

Reloaded 0 of 773 
libraries in 169ms.
flutter: ChatsList
flutter: RequestsList
flutter: POSTS LENGTH
flutter: ConnectionState.waiting
flutter: 1
flutter: RequestsList
flutter: POSTS LENGTH
flutter: ConnectionState.waiting
flutter: 0
flutter: ChatsList
flutter: RequestsList
flutter: POSTS LENGTH
flutter: ConnectionState.waiting
flutter: 0
flutter: ChatsList
like image 730
Mohamed Mohamed Avatar asked Aug 27 '19 04:08

Mohamed Mohamed


1 Answers

I know this is late but moving the stream outside of the build context either using your init method, or using provider to do the call in a services file is how I do my setups. Let me know if you came right.

like image 110
Wesley Barnes Avatar answered Oct 19 '22 11:10

Wesley Barnes