Global Stream with multiple listeners

1,526

StreamBuilder automatically starts and ends listening of provided stream:, so there will be no problem when using one broadcast stream in multiple places around the app. Even nested listening to one stream is not an issue.

Here are some helpful links if you want to dig deeper:

Share:
1,526
Morez
Author by

Morez

Currently studying BSc Computer Science at Birkbeck University. Very passionate and interested in Programming and Mathematics. Familiar with Python, Java, VB.Net and Dart programming languages and Flutter SDK. I also have worked with SQL(MySQL) and NoSQL(Firebase) database systems and also REST APIs. Admin of mo_programming_quotes Instagram page where I post interesting programming quotes. My email address: [email protected] Check out my GitHub repository for interesting programming articles

Updated on December 17, 2022

Comments

  • Morez
    Morez over 1 year

    I have a stream connected to a Firebase document and I am constantly listening to any changes of the document.

    I want to update some parts of my app when document is changed so I made the stream globally available and I use StreamBuilders on different screens so the latest data will be available ob the screen.

    Will there be a problem with the global stream and multiple StreamBuilders? How does the app work when the StreamBuilders are created on multiple screens?

    This is my global stream:

    Stream userDocGlobalStream =
            Firestore.instance.collection("user").document(CurrentUserDetails.id).snapshots();
    
    
    

    This is the build method of one of my screens widget (I change the color of a button depending on the stream data):

      @override
      Widget build(BuildContext context) {
        final ThemeData theme = Theme.of(context);
        return StreamBuilder(
          stream: userDocGlobalStream,
          builder: (context, snapShot) {
            return Card(
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(30),
                  side: BorderSide(color: theme.primaryColor)),
              elevation: 30,
              child: Container(
                margin: EdgeInsets.all(10),
                child: Column(
                  children: <Widget>[
                    Column(
                      crossAxisAlignment: CrossAxisAlignment
                          .stretch, //need to use it to strech the items horizontally
                      children: <Widget>[
                        Container(
                          //to think, it is used for the background color of the picture. can undo it later
                          decoration: BoxDecoration(
                            color: theme.primaryColor.withAlpha(10),
                            borderRadius: BorderRadius.circular(10),
                          ),
                          padding: EdgeInsets.all(10),
                          child: GestureDetector(
                            onTap: () {}, //go to user profile when pressed.
                            child: CircleAvatar(
                              radius: 70,
                              backgroundImage: NetworkImage(userImageUrl),
                            ),
                          ),
                        ),
                      ],
                    ),
                    Container(
                      margin: EdgeInsets.symmetric(vertical: 10),
                      child: FittedBox(
                        child: Text(
                          "Username : $username ",
                        ),
                      ),
                    ),
                    Container(
                      margin: EdgeInsets.symmetric(vertical: 10),
                      child: FittedBox(
                        child: Text(
                          "interests : ${interests.toString().replaceAll("[", "").replaceAll("]", "")} ",
                        ),
                      ),
                    ),
                    Container(
                      margin: EdgeInsets.symmetric(vertical: 10),
                      child: FittedBox(
                        child: Text("Distance from you : $distanceFromUser KM"),
                      ),
                    ), //to do address and km from you should go here
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: <Widget>[
                        IconButton(
                          color: theme.primaryColor,
                          icon: Icon(Icons.chat),
                          onPressed: () {}, //send a message to the user
                        ),
                        IconButton(
                            color: Colors.cyan,
                            icon: CurrentUserDetails.friendRequestsSent.contains(
                                    userId) //to do=> THE ICON MUST CHANGE WITH EVERY CHANGE OF THE DATA
                                ? Icon(
                                    Icons.person,
                                    color: Colors.black,
                                  )
                                : CurrentUserDetails.friends.contains(userId)
                                    ? Icon(
                                        Icons.person,
                                        color: Colors.green,
                                      )
                                    : Icon(Icons.person_add),
                            onPressed: () {
                              try {
                                //to do
                                CurrentUserDetails.friendRequestsSent
                                        .contains(userId)
                                    ? DoNothingAction()
                                    //Cancel the sent request:
                                    : CurrentUserDetails.friendRequestsReceived
                                            .contains(userId)
                                        ? DoNothingAction()
                                        //accept friend request:
                                        : CurrentUserDetails.friends
                                                .contains(userId)
                                            ? DoNothingAction()
                                            //delete the friend:
                                            : DatabaseManagement().sendFriendRequest(
                                                CurrentUserDetails.id,
                                                userId); //userId is the id of the user we are showing the widget for
                              } catch (e) {
                                showDialog(
                                  context: context,
                                  builder: (ctx) => DialogueWidget(
                                    titleText: "Error occured",
                                    contentText:
                                        e.toString(), //to do+> change the er
                                  ),
                                );
                              }
                            } //send friend request when this button is pressed
                            ),
                        IconButton(
                          color: Colors.red[300],
                          icon: Icon(Icons.location_on),
                          onPressed:
                              () {}, //show a map with a users location details on it.
                        )
                      ],
                    )
                  ],
                ),
              ),
            );
          },
        );
      }
    }
    
    
  • foobar8675
    foobar8675 about 3 years
    I had this same question,thanks Marcin. I am not following something however, with multiple listeners on streams, why do we need state management like Provider or Riverpod? Couldn't one or several flutter page/widgets listen to a firebase stream for it's updated data?