I have a problem, it is that i have to reload app to refresh the widget (TableCalendar), i know that there is a setState to detect changes and reload but... i supose i have to execute again the method getData where i have all the information about the events and reload the calendar but i don't know how can i do it.
Here is the init state where i call getData to get the data.
void initState() {
super.initState();
getData();
Future.delayed(const Duration(seconds: 3), () {
_selectedDay = _focusedDay;
_selectedEvents = ValueNotifier(_getEventsForDay(_selectedDay!));
FirebaseFirestore.instance
.collection("usuaris")
.doc(usuari!.uid)
.get()
.then((value) {
this.usuariActual = ModelUsuari.fromMap(value.data());
setState(() {});
});
});
}
getData is in other class
Future<void> getData() async {
User? usuari = FirebaseAuth.instance.currentUser;
final allDataGlobal = <RegistreSentiment>[];
CollectionReference collectionRef = FirebaseFirestore.instance
.collection('usuaris')
.doc(usuari!.uid)
.collection('Registre sentiments');
final registresRef = collectionRef.withConverter<RegistreSentiment>(
fromFirestore: (snapshot, _) =>
RegistreSentiment.fromMapData(snapshot.data()!),
toFirestore: (notaActual, _) => notaActual.toMap(),
);
List<QueryDocumentSnapshot<RegistreSentiment>> registresUsuari =
await registresRef.get().then((snapshot) => snapshot.docs);
registresUsuari.forEach((doc) => {
allDataGlobal.add(doc.data()),
// convert this Map to your custom object and add it to your list
});
for (var dataRegistre in allDataGlobal) {
DateTime tempDate = DateTime.fromMicrosecondsSinceEpoch(
dataRegistre.dataRegistreTS!.microsecondsSinceEpoch);
// dataRegistre.dataRegistre = DateFormat("yyyy-MM-dd").format(tempDate);
dataRegistre.dataRegistre = tempDate;
}
for (var element in allDataGlobal) {
_kEventSource[DateTime(
element.dataRegistre!.year,
element.dataRegistre!.month,
element.dataRegistre!.day,
)] = _kEventSource[DateTime(
element.dataRegistre!.year,
element.dataRegistre!.month,
element.dataRegistre!.day,
)] !=
null
? [
...?_kEventSource[DateTime(
element.dataRegistre!.year,
element.dataRegistre!.month,
element.dataRegistre!.day,
)],
element
]
: [element];
}
}
Then i should press the button to add event and reload both... getData and the tablecalendar This part of code is where i have to reload or refresh both.
Padding(
padding: EdgeInsets.only(bottom: 40),
child: FloatingActionButton(
onPressed: () {
Comment = commentController.text;
submit();
SaveToFirebase(
Comment, elecc, _selectedDay!);
},
child: const Icon(Icons.save),
backgroundColor: Colors.green,
),
)
],
The main problem is that GetData, have an method that is async
List<QueryDocumentSnapshot<RegistreSentiment>> registresUsuari =
await registresRef.get().then((snapshot) => snapshot.docs);
When the compiler arrives at this part, while it is being processed, it passes to the method below, which is to put the events on the calendar, but of course if the await has not finished yet, the method is empty, so they will not be loaded.
This is the method:
final kEvents = LinkedHashMap<DateTime, List<RegistreSentiment>>(
equals: isSameDay,
hashCode: getHashCode,
)..addAll(_kEventSource);
So.. That's why at the begining of the code i use a Future.delayed because i have to wait to the getData, but if i don't put the Delay, happens what i said.
If you help me you will make me very happy... i spent a lot of hours with this... <3
You must remove the then method, you are already using await, your query will wait for the docs to return.
var querySnapshot = await registresRef.get();
List<QueryDocumentSnapshot<RegistreSentiment>> registresUsuari = querySnapshot.docs;
Remove the forEach it is synchronous, only the interaction inside it is async, but the return is sync. Use for which is async.
for(var doc in registresUsuari){
allDataGlobal.add(doc.data());
}