Перезагрузите TableCalendar (для событий) с помощью firebase

У меня проблема, я должен перезагрузить приложение, чтобы обновить виджет (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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны удалить метод then, вы уже используете ожидание, ваш запрос будет ждать возврата документов.

  var querySnapshot = await registresRef.get();
  List<QueryDocumentSnapshot<RegistreSentiment>> registresUsuari = querySnapshot.docs;

Удалите forEach, он синхронный, только взаимодействие внутри него асинхронное, а возврат синхронный. Использование для которого является асинхронным.

for(var doc in registresUsuari){
  allDataGlobal.add(doc.data());
}

Он делает то же самое... Он запускается, но переходит к kEvents, где значение null, потому что он еще не получил результатов. Метод не ждите, продолжайте и продолжайте с кодом

Albert mora costillo 11.10.2022 02:19

Правильно, но я не понял этого RegistreSentiment в , в List<QueryDocumentSnapshot<RegistreSentiment>>. Что он такое? Это определение типа для Map<String, dynamic>.

Chance 11.10.2022 02:29

Я обновил ответ, посмотрите, решает ли он, если возможно, добавьте точку останова в местах, где вы получаете нуль, чтобы вы могли проверить все переменные.

Chance 11.10.2022 02:34

Возьмите информацию из firebase, и из этого списка мы преобразуем каждый объект в списке в тип RegistreSentiment.

Albert mora costillo 11.10.2022 09:39

в основном ожидание не работает, и метод не ждет, пока он не завершится.

Albert mora costillo 11.10.2022 14:47

Я разместил изображение, если это будет лучше понять...

Albert mora costillo 11.10.2022 15:13

Смотри, я сделал тест в том же формате, что и твоя функция. До for(var element in allDataGlobal) проблем нет, все паузы соблюдаются, так что проблема не в ожидании, скорее всего в секции, которая собирает список событий, как я уже говорил добавляйте точку останова в том месте, где вы видите нулевое значение, делайте это с помощью vscode или android studio довольно просто.

Chance 12.10.2022 00:17

Другие вопросы по теме