Как я могу решить, тип «Timestamp» не является подтипом типа «String» в приведении типа - PullRequest
2 голосов
/ 22 марта 2020

Я хочу получить собрания из Firestore и отобразить их в следующую Meeting модель:

part 'meeting.g.dart';

@JsonSerializable(explicitToJson: true)
class Meeting {
  String id;
  DateTime date;

  Meeting(this.id, this.date);

  factory Meeting.fromJson(Map<String, dynamic> json) {

    return _$MeetingFromJson(json);
  }

  Map<String, dynamic> toJson() => _$MeetingToJson(this);
}

Документы извлекаются из Firestore, а затем fromJson вызывается для повторяемого, но исключение брошено:

type 'Timestamp' is not a subtype of type 'String' in type cast

Когда я go в сгенерированный meeting.g.dart, именно эта строка вызывает ошибку

json['date'] == null ? null : DateTime.parse(json['date'] as String)

Чтобы обойти проблему, я попытался изменить с DateTime to Timestamp в модели, но затем отображается следующая ошибка сборки:

Error running JsonSerializableGenerator
Could not generate `fromJson` code for `date`.
None of the provided `TypeHelper` instances support the defined type.

Не могли бы вы рассказать мне, как решить эту проблему? Есть ли другой предпочтительный способ объединить Firebase и проект Flutter, используя json_serializable для сериализации JSON? Может быть, даже заменить использование json_serializable?

Ответы [ 2 ]

2 голосов
/ 30 марта 2020

Спасибо @Reed, за указание в правильном направлении. При передаче значения DateTime в FireStore у firebase не возникает проблем с принятием этого значения как Timestamp, однако при возврате его необходимо правильно обработать. В любом случае, вот пример, который работает в обоих направлениях:

2 голосов
/ 23 марта 2020

Решение # 1

Используйте функции конвертера toJson и fromJson, как в следующем примере: https://github.com/dart-lang/json_serializable/blob/master/example/lib/example.dart

Преимущества решения в том, что вы не нужно жестко кодировать имена свойств

Решение # 2

После прочтения https://github.com/dart-lang/json_serializable/issues/351 я изменил Meeting.fromJson, и теперь он работает, как и ожидалось :

  factory Meeting.fromJson(Map<String, dynamic> json) {
    json["date"] = ((json["date"] as Timestamp).toDate().toString());
    return _$MeetingFromJson(json);
  }

json["date"] - это Timestamp по умолчанию, я конвертирую его в String, прежде чем он достигнет сгенерированного десериализатора, поэтому он не обрабатывает sh при попытке привести json["date"] as String

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

В качестве альтернативы можно попробовать https://pub.dev/packages/built_value для serialiazion, что рекомендуется в их блоге https://flutter.dev/docs/development/data-and-backend/json

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...