0

Currently my database looks like this:

enter image description here

Creating a Leaderboard has been fairly simple and straightforward so far:

I declare my stream in initState:

  @override
  void initState() {
    futureAd = fetchAd();
    _mainScoreStream = FirebaseFirestore.instance
        .collection('users')
        .orderBy('current_score', descending: true)
        .where('current_score', isGreaterThan: 0)
        .limit(25)
        .snapshots();
    super.initState();
  }

Then use it in a ListView.builder:

            Expanded(
              child: ListView.builder(
                physics: const BouncingScrollPhysics(),
                itemBuilder: (context, index) {
                  DocumentSnapshot data = snapshot.data!.docs[index];
                  return LeaderboardCard(
                    currentScore: data['current_score'].toString(),
                    name: data['name'],
                    index: index,
                    isCurrentUser: data.id == user!.uid,
                  );
                },
                itemCount: snapshot.data!.docs.length,
              ),
            ),

But this makes it so that each users puts on an extra 25 reads when loading the Leaderboard

How can I create a Firebase Function that grabs the name + current_score and puts that in a separate leaderboard document that a user can fetch instead so the reads can be cut to 1 instead of 25, or is there any other way to cut down reads while creating a leaderboard ?

  • 1
    "How can I create a Firebase Function that grabs the name + current_score" What have you tried? – Renaud Tarnec Feb 01 '22 at 13:25
  • @RenaudTarnec Currently nothing, still trying to figure out how to even get both of those and put them in a document so I could fetch them together – FlutterChicken Feb 01 '22 at 13:39
  • Writing such a function for you is a bit too broad for Stack Overflow, but if you tried and get stuck: post back with a [minimal repro](http://stackoverflow.com/help/mcve) and we can more likely help. I recommend reading Dan's answer here for more on such a leaderboard ranking (though it also doesn't contain a copy/paste implementation): https://stackoverflow.com/questions/46720997/leaderboard-ranking-with-firebase/46732461#46732461 – Frank van Puffelen Feb 01 '22 at 14:50

1 Answers1

1

One approach would be to create a separate leaderboard collection with a single document (or one per date, if you care about the data historically) with the leaderboard data (userId, name, current score), then use a Function with a Firestore Trigger that fires anytime a user document is updated and, if the user's score is updated, updates the leaderboard document.

Alternatively, anytime a user's score is updated you could write directly to both the user document and the leaderboard document and skip the function altogether.

Tim
  • 2,843
  • 13
  • 25