具有多个侦听器的全局流

Global Stream with multiple listeners

我有一个连接到 Firebase 文档的流,我一直在监听文档的任何更改。

我想在文档更改时更新我的​​应用程序的某些部分,因此我使流在全球可用,并且我在不同的屏幕上使用 StreamBuilders,以便屏幕上可以使用最新数据。

全局流和多个StreamBuilder会不会有问题?在多个屏幕上创建 StreamBuilder 时应用程序如何工作?

这是我的全局流:

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

StreamBuilder 自动开始和结束侦听提供的stream:,因此在应用程序周围的多个位置使用一个广播流时不会有问题。即使嵌套收听一个流也不是问题。

如果您想深入了解,这里有一些有用的链接: