Hello FlutterFlow Community,
I’m currently working on a feature to generate a calendar with training days fetched from Firestore. The goal is to display a calendar for a given month and mark the days that have training sessions with their info. However, I’m facing performance issues when dealing with a larger number of training days, which makes the process very slow.
Problem:
The performance degrades significantly when fetching around 50 training days from Firestore, leading to slow calendar rendering times. Although the optimized solution I tried using a map for caching improves speed, it still does not fully solve the issue, and it fails to properly identify and mark training days in the calendar.
Here’s the current implementation:
// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
Future<List<CalendarDayStruct>> getCalendarForMonthAction(
DateTime inputDate,
List<DocumentReference> trainingDayRefs,
) async {
List<CalendarDayStruct> calendar = [];
Map<String, Map<String, dynamic>> trainingDaysMap = {};
try {
// Fetch all training days from Firestore and cache them
for (DocumentReference ref in trainingDayRefs) {
DocumentSnapshot snapshot = await ref.get();
if (snapshot.exists) {
DateTime trainingDate = (snapshot.get('Date') as Timestamp).toDate();
DocumentReference trainingRef = snapshot.get('TrainingRef');
List<String> templateDiarioStringList =
List<String>.from(snapshot.get('TemplateDiarioStringList') ?? []);
String key = trainingDate.toIso8601String().substring(0, 10);
trainingDaysMap[key] = {
'date': trainingDate,
'trainingRef': trainingRef,
'templateDiarioStringList': templateDiarioStringList,
'trainingdayRef': ref,
};
}
}
// Start by finding the first day of the current month
DateTime firstOfMonth = DateTime(inputDate.year, inputDate.month, 1);
// Find the last day of the current month
DateTime lastOfMonth = DateTime(inputDate.year, inputDate.month + 1, 0);
// Find the first Monday on or before the first of the month
DateTime startCalendar =
firstOfMonth.subtract(Duration(days: firstOfMonth.weekday - 1));
// Find the last Sunday after the end of the month
DateTime endCalendar = lastOfMonth.weekday == 7
? lastOfMonth
: lastOfMonth.add(Duration(days: 7 - lastOfMonth.weekday));
// Populate the calendar using cached training days
for (DateTime date = startCalendar;
date.isBefore(endCalendar.add(Duration(days: 1)));
date = date.add(Duration(days: 1))) {
bool isPreviousMonth = date.isBefore(firstOfMonth);
bool isNextMonth = date.isAfter(lastOfMonth);
DocumentReference? trainingRef;
DocumentReference? trainingdayRef;
bool isTrainingDay = false;
List<String> templateDiarioStringList = [];
String key = date.toIso8601String().substring(0, 10);
if (trainingDaysMap.containsKey(key)) {
var item = trainingDaysMap[key]!;
isTrainingDay = true;
trainingRef = item['trainingRef'] as DocumentReference;
templateDiarioStringList =
item['templateDiarioStringList'] as List<String>;
trainingdayRef = item['trainingdayRef'] as DocumentReference;
}
CalendarDayStruct dayStruct = CalendarDayStruct(
calendarDate: date,
isPreviousMonth: isPreviousMonth,
isNextMonth: isNextMonth,
isTrainingDay: isTrainingDay,
trainingRef: trainingRef,
teplateDiarioStringList: templateDiarioStringList,
trainingDayDocRef: trainingdayRef,
);
calendar.add(dayStruct);
}
} catch (e) {
print('Error fetching training days: $e');
}
return calendar;
}