2

What is the best way to return a document from firebase when the id is not coming from the json firestore returns, using a freezed data class with fromJson/toJson?

I want the id to be required (to make sure I always have one - and plan to use an "uninstantiated ID" for objects that haven't been saved to firestore yet).

But if I mark id as required, but ignore it for json generation, the fromJson doesn't work when I try to do code generation. Is there a way to have code generation work where I specify a second parameter in the fromJson method to pass in id separately?

Here is my base data class:

@freezed
class Habit with _$Habit {
  const Habit._();

  const factory Habit({
    @JsonKey(includeFromJson: false, includeToJson: false) required String id,
    required String title,
    String? description,
  }) = _Habit;

  factory Habit.newEmpty({required String userId}) => Habit(
        id: uninstantiatedId,
        title: '',
      );

// Ideally would like to have this take a string
// id in addition to the json, and set the id to
// what is passed in separately.
  factory Habit.fromJson(String id, Map<String, dynamic> json) => _$HabitFromJson(json);
}
Charlie Page
  • 541
  • 2
  • 17

1 Answers1

0

So I can't do it with the id property set as non-nullable but without a default value. I either need to make id a nullable String? type, or set a @Default('textvalue') for the id.

Then I can add the copyWith method to my fromJson method which seems to work. Updated code below:

@freezed
class Habit with _$Habit {
  const Habit._();

  const factory Habit({
    // I have to add a default value, as pictured below, or set this to
    // String? so it is optional. Otherwise the json_serializable code
    // will not be generated.
    @JsonKey(includeFromJson: false, includeToJson: false) @Default(uninstantiatedId) String id,
    required String title,
    String? description,
  }) = _Habit;

  factory Habit.newEmpty({required String userId}) => Habit(
        id: uninstantiatedId,
        title: '',
      );

    // I then add the copyWith to my fromJson portion to add the id
  factory Habit.fromJson(String id, Map<String, dynamic> json) => _$HabitFromJson(json).copyWith(id: id);
}
Charlie Page
  • 541
  • 2
  • 17