Необработанное исключение: ошибка NoSuchMethodError: метод ‘ToDate’ был вызван при null

#dart #flutter #google-cloud-firestore

#dart #флаттер #google-cloud-firestore

Вопрос:

Я разрабатываю приложение для общения в чате, используя Firebase.

в течение некоторого времени я получаю эту ошибку Unhandled Exception: NoSuchMethodError: The method 'toDate' was called on null.

Получение ошибки при преобразовании Timestamp в DateTime using toDate() .

НЕКОТОРОЕ ВРЕМЯ ВЫДАЕТ ОШИБКУ, а ЗАТЕМ ОШИБКА ИСЧЕЗАЕТ.

ПОЖАЛУЙСТА, РАССМОТРИТЕ ЭТОТ GIF.

ЭТО

ЗДЕСЬ ТИП ДАННЫХ FIRESTORE УКАЗАН КАК TimeStamp .

введите описание изображения здесь

ИСХОДНЫЙ КОД

 class ChatMessageModel {
  bool isSentByMe;
  String msg = '';

  ///SERVER TIME
  Timestamp time;
  DateTime localTime;
  String timeStamp;
  String fromUid;
  String toUid;

  ChatMessageModel._();

  ChatMessageModel.fromSnapshot(DocumentSnapshot snapshot) {
    this.isSentByMe =
        snapshot.data['from'] == LoginBloc.instance.firebaseUser.uid;
    this.msg = snapshot.data['msg'];
    this.timeStamp = snapshot.data['time'].toString();
    this.time = snapshot.data['time'];
    this.fromUid = snapshot.data['from'];
    this.toUid = snapshot.data['to'];
    this.localTime = this.time.toDate(); //ERROR
  }
}
  

ЗАРАНЕЕ СПАСИБО.

Комментарии:

1. попробуйте snapshot.data['time'].toDate

2. пытался. ничего не изменилось.

3. Похоже, что в firestore api есть ошибка. StreamBuilder метод builder вызывался 2 раза, сначала с нулевым значением timestamp , а второй с ненулевыми значениями.

4. Учебный курс Angela’s Flutter в Udemy? У меня точно такая же ошибка с приложением Flash Chat.

Ответ №1:

Он выдает ошибку, потому что во время вызова this.time значение this.time равно нулю. Поэтому функция ToDate() не может применяться при null

Попробуйте изменить :
this.localTime = this.time.toDate();

Для :

 this.localTime = this.time == null ? DateTime.now()
    : this.time.toDate();
  

ИЛИ вы можете использовать следующим образом :

 String stringtime = widget.time == null
        ? DateTime.now().toString()
        : widget.time.toDate().toString();
    // stringtime = widget.time.toDate().toString();
    DateTime date = DateTime.parse(stringtime);
    String clocktime = DateFormat('hh:mm a').format(date);
  

Надеюсь, это поможет, у меня сработало 🙂

Ответ №2:

Ваш код пытается преобразовать time в Date перед его извлечением, коротким обходным путем было бы инициализировать вашу time переменную текущим временем до загрузки значения сервера:

   Timestamp time = new Timestamp( new Date(2019,3,4) );
  

другим решением было бы использовать async метод для await значения с сервера перед его преобразованием, что вы не можете себе позволить, учитывая, что вы хотите использовать его в мгновенной рассылке сообщений.Подробнее можно найти в официальной документации Firebase и документации разработчика Android.

Обратите внимание, что приведенный выше код приведет к Timestamp указанию на полночь, но это не должно быть проблемой, поскольку это короткий заполнитель по сравнению со скоростью отклика Firebase.

Комментарии:

1. DateTime.now().millisecondsSinceEpoch не может быть преобразован во временную метку.

2. Я исправил ошибку, надеюсь, это решит вашу проблему

3. я слушаю поток firebase и пока не узнаю, что streams обновляет значение только при изменении некоторого значения в этом потоке. Поэтому данные должны быть загружены в виде моментального снимка.

Ответ №3:

попробуйте изменить

 this.localTime = this.time.toDate();
  

Для

 this.localTime = this.time.toDate()==null?DateTime().now():this.time.toDate();
  

для лучшей читаемости сохраните this.time.toDate() в переменной.Надеюсь, это поможет, сработало для меня

Ответ №4:

У меня этот код сработал:

 ds['time'] == null? Text(DateTime.now().toString())
  : Text(
   DateFormat("hh:mm a").format(
   ds['time'].toDate(),
 ),
),