У меня проблема, я должен перезагрузить приложение, чтобы обновить виджет (TableCalendar), я знаю, что есть setState для обнаружения изменений и перезагрузки, но... я полагаю, мне нужно снова выполнить метод getData, где у меня есть всю информацию о событиях и перезагрузить календарь, но я не знаю, как мне это сделать.
Вот состояние инициализации, когда я вызываю getData для получения данных.
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 находится в другом классе
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];
}
}
Затем я должен нажать кнопку, чтобы добавить событие и перезагрузить оба... getData и tablecalendar В этой части кода мне нужно перезагрузить или обновить оба.
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,
),
)
],
Основная проблема заключается в том, что GetData имеет асинхронный метод.
List<QueryDocumentSnapshot<RegistreSentiment>> registresUsuari =
await registresRef.get().then((snapshot) => snapshot.docs);
Когда компилятор достигает этой части, пока она обрабатывается, он переходит к методу ниже, который должен поместить события в календарь, но, конечно, если ожидание еще не завершено, метод пуст, поэтому они будут не загружаться.
Это метод:
final kEvents = LinkedHashMap<DateTime, List<RegistreSentiment>>(
equals: isSameDay,
hashCode: getHashCode,
)..addAll(_kEventSource);
Итак.. Вот почему в начале кода я использую Future.delayed, потому что мне нужно дождаться getData, но если я не поставлю задержку, произойдет то, что я сказал.
Если вы поможете мне, вы сделаете меня очень счастливым... я провел много часов с этим... <3





Вы должны удалить метод then, вы уже используете ожидание, ваш запрос будет ждать возврата документов.
var querySnapshot = await registresRef.get();
List<QueryDocumentSnapshot<RegistreSentiment>> registresUsuari = querySnapshot.docs;
Удалите forEach, он синхронный, только взаимодействие внутри него асинхронное, а возврат синхронный. Использование для которого является асинхронным.
for(var doc in registresUsuari){
allDataGlobal.add(doc.data());
}
Правильно, но я не понял этого RegistreSentiment в , в List<QueryDocumentSnapshot<RegistreSentiment>>. Что он такое? Это определение типа для Map<String, dynamic>.
Я обновил ответ, посмотрите, решает ли он, если возможно, добавьте точку останова в местах, где вы получаете нуль, чтобы вы могли проверить все переменные.
Возьмите информацию из firebase, и из этого списка мы преобразуем каждый объект в списке в тип RegistreSentiment.
в основном ожидание не работает, и метод не ждет, пока он не завершится.
Я разместил изображение, если это будет лучше понять...
Смотри, я сделал тест в том же формате, что и твоя функция. До for(var element in allDataGlobal) проблем нет, все паузы соблюдаются, так что проблема не в ожидании, скорее всего в секции, которая собирает список событий, как я уже говорил добавляйте точку останова в том месте, где вы видите нулевое значение, делайте это с помощью vscode или android studio довольно просто.
Он делает то же самое... Он запускается, но переходит к kEvents, где значение null, потому что он еще не получил результатов. Метод не ждите, продолжайте и продолжайте с кодом