Глобальный поток с несколькими слушателями - PullRequest
2 голосов
/ 11 февраля 2020

У меня есть поток, связанный с документом Firebase, и я постоянно прислушиваюсь к любым изменениям документа.

Я хочу обновить некоторые части моего приложения при изменении документа, чтобы я сделал поток доступным для всех пользователей. и я использую StreamBuilders на разных экранах, чтобы на экране были доступны последние данные.

Будет ли проблема с глобальным потоком и несколькими StreamBuilders? Как работает приложение, когда StreamBuilders создаются на нескольких экранах?

Это мой глобальный поток:

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


Это метод сборки одного из моих виджетов экранов (я изменяю цвет кнопки в зависимости от данных потока):

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

1 Ответ

1 голос
/ 11 февраля 2020

StreamBuilder автоматически запускается и завершает прослушивание предоставленного stream:, поэтому не будет проблем при использовании одного широковещательного потока в нескольких местах вокруг приложения. Даже вложенное прослушивание одного потока не является проблемой.

Вот несколько полезных ссылок, если вы хотите копать глубже:

...