#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(),
),
),