2
votes

I'm developing a project in Flutter for the first time and am trying to find the best way to organize my Firestore DB. I believe I have it the way I want it but can't figure out how to query it correctly.

I have a user with an ID to a collection that associates a player profile to their user profile (in separate collections).

I need to:

  1. grab the Firebase currentUser uid
  2. find the associated player profile
  3. Get the event IDs saved to the player profile
  4. list of events based on their IDs

I'm guessing in that order.

DatabaseReference getCurrentUserRef() async {
    return this.usersRef.child((await this.getCurrentUser()).uid);
  }

var user = await getCurrentUserRef()
var _playerEvents = [];

db.collection('player').where('id', isEqualto: user).get().then((doc) => {
   db.collection('player').doc(doc.data().id).collection('events').get().then((snapshot) => {
      snapshot.forEach(doc) {
         _playerEvents.push(doc.data().id);
      }
   });
});

Then with that array i need to get all the events based on those id (if there are any)

_playerEvents.forEach(event) {
    db.collection('events').where('id', isEqualTo: event).get().then((doc) => {
         //somehow popular a Map or JSON that I can show in a list view on the page for the events associated with that player
         List_Item for display
    });
}

Here are some screens to my DB. I am learning Flutter which uses dart. Any help would be amazing.

User Collection

Player Collection

Events Collection

2

2 Answers

0
votes

I'm not very familiar with flutter so I can't help you on the codes.

But to nudge you along the right path:

Firestore is asynchronous. So to do all your 4 steps above, you need to do them with callbacks.

I don't think you can cascade the queries in that way (if it's similar to Java, you can not do that).

What you need to do is introduce callbacks after each query is done so you have enough information to do your next query.

0
votes

I actually just ended up switching my database around and queried one collection that contains an array with a certain value.

Widget _buildTeamList() {
    return Container(
      child: Center(
        child: StreamBuilder(
            stream: Firestore.instance
                .collection('teams')
                .where("players", arrayContains: user['player_id'])
                .snapshots(),
            builder: (context, snapshot) {
              if (!snapshot.hasData) return const Text('Loading...');
              return ListView.builder(
                itemCount: snapshot.data.documents.length,
                itemBuilder: (context, index) =>
                    _buildTeamItem(context, snapshot.data.documents[index]),
              );
            }),
      ),
    );
  }

This has worked really well.