0
votes

The Firestore database is build of one collection of users. Every user document has some public data and a array of users ID's that he follows called following. In the Flutter app I would like to create a StreamBuilder on the following array. So when the user adds someone to his following array - it would be added to the stream, and when a user from the following list changes his data - the stream would update too.

I thought maybe to use a list of references ('users/usersid3') instead of a list of IDs ('userid3'), but I don't know how to implement it.

This is how the database is structured.

users
      - user1id
            - some public data
            - following: [user2id, user3id]
      - user2id
            - some public data
            - following: []
      - user3id
            - some public data
            - following: [user2id]
1
Does this answer help? stackoverflow.com/a/50553853/10747134 - user10747134
@OneLunchMan Thanks for the reference, but I can't see how that would help. That answer explains how to use the StreamBuilder in it's basic form. I need to use it on a selection of documents from the collection as I explained in the question. - Zvi Karp
Oh, I see more of the issue. So Firebase doesn't like working with "changes" in an array, so it'd be easier to make it a map of following IDs with the info you want from them. From there, use the streambuilder for the one user (instead of the collection, it's a doc reference, but basically the same code), and pass the returned doc into your display component that can process list items from the map keys. - user10747134
@OneLunchMan I like your idea. I forgot to mention that there are a lot of users that are following others, this means that we well be saving multiple copies of the public data in the user following maps, and doing a lot of updates every time someone changes his public data (=expensive in storage and writes). - Zvi Karp

1 Answers

0
votes

So, there is a workaround to solve this problem.

  1. I saved the following list as map (named 'followingMap') in a separate document 'followingDoc').
  2. Used a StreamBuilder on that document:
StreamBuilder(
  stream: Firestore.instance.collection('users').document(uid).collection('data').document('followingDoc').snapshots(),
  builder: (context, snapshot) {
    if (!snapshot.hasData) return Text("No data");
    return ListView.builder(
      itemCount: snapshot.data['followingMap'].keys.toList().length,
      itemBuilder: (BuildContext context, int index) {
        return followingItemWidget(id: snapshot.data['followingMap'].keys.toList()[index]);
      }
    );
  },
)
  1. And last I created a widget called 'followingItemWidget' that has a StreamBuilder on a document of a user who I follow.

This works perfectly, although I believe that there should be a way to do it with only one StreamBuilder.