Reputation: 57
I want to show a list of top 25 players (fetched from Firestore) on a screen and currently this is how I implemented it:
late final Stream<QuerySnapshot> _mainScoreStream;
@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();
}
@override
Widget build(BuildContext context) {
// Used to make text size automaticaly sizeable for all devices
final double unitHeightValue = MediaQuery.of(context).size.height * 0.01;
final user = Provider.of<UserModels?>(context);
return SafeArea(
child: StreamBuilder<QuerySnapshot>(
stream: _mainScoreStream,
// ignore: missing_return
builder: (context, snapshot) {
if (snapshot.hasData) {
return Expanded(
child: ListView.builder(
physics: 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,
),
);
} else if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
strokeWidth: 2.0,
),
);
}
return Container();
},
),
);
}
}
The leaderboard changes once a day, however with this implementation I get an extra 25 reads per user.
Is there a more efficient way to fetch this data or is this okay since my daily reads per one user are around 30 ?
EDIT: I am aware that over optimizing my reads/writes is not a good practice, but currently based on Firebase Pricing Calculator this could lead to a lot of daily reads, so not sure how to go about it, I could always decrease the limit or remove the Leaderboard completely
Upvotes: 0
Views: 110
Reputation: 599946
If you change the leaderboard once per day, you could:
Calculate the leaderboard contents on a trusted system (your development machine, a server that you control, or Cloud Functions/Cloud Run), and store that in a separate document in Firestore. Then each client only has to read that document to get the entire leaderboard.
Create a data bundle with the query results each day on a trusted system, and distribute that to your users through a cheaper system (e.g. Cloud Storage or even as a document in Firestore again).
Upvotes: 1