Charlie Page
Charlie Page

Reputation: 831

json_serializable can't convert datetime to timestamp for firestore

I am using Json_serializable to convert a class for firestore, and I'm having trouble with converting a DateTime - I keep getting the following error:

_TypeError (type 'Timestamp' is not a subtype of type 'String' in type cast)

The object I'm converting is not just a DateTime, but a custom Date class which stores a DateTime but has some additional enforcement logic to make sure it's always the beginning of a specific date:

class Date {
  final DateTime value;

  const Date._(this.value);

  factory Date(DateTime value) {
    return Date._(value.startOfDateUtc());
  }

  factory Date.fromDatabase(DateTime value) {
    if (value.isStartOfDateUtc()) {
      return Date._(value.toUtc());
    } else {
      return Date._(value.startOfDateUtc());
    }
  }

  factory Date.now() {
    return Date(DateTime.now());
  }
}

And it has the following converter:

/// This converts a date to a Timestamp and vice versa for Firestore.
class FirestoreDateConverter implements JsonConverter<Date, Timestamp> {
  const FirestoreDateConverter();

  @override
  Date fromJson(Timestamp value) {
    return Date(value.toDate());
  }

  @override
  Timestamp toJson(Date date) => Timestamp.fromDate(date.value);
}

Which is then specified in my habit class:

@JsonSerializable(includeIfNull: false)
class Habit {
  @JsonKey(includeFromJson: false, includeToJson: false)
  final String id;
  @ItemTitleConverter()
  final ItemTitle title;
  final String? description;
  @FirestoreDateConverter()
  final Date startDate;
  @FirestoreDateConverter()
  final Date? endDate;
...

The weird thing is, in the json_serializable code that is generated, it converts the DateTime to a string:

Habit _$HabitFromJson(Map<String, dynamic> json) => Habit(
      title: const ItemTitleConverter().fromJson(json['title'] as String),
      description: json['description'] as String?,
      startDate: DateTime.parse(json['startDate'] as String),
      endDate: json['endDate'] == null
          ? null
          : DateTime.parse(json['endDate'] as String),
...

Any idea what could be causing this issue?

Upvotes: 2

Views: 948

Answers (1)

Wai Han Ko
Wai Han Ko

Reputation: 1043

Type cast using Timestamp

 startDate: (json["startDate"] as Timestamp).toDate(),
 endDate: (json["startDate"] as Timestamp).toDate(),

Upvotes: 1

Related Questions