1

In Firestore my documents are structured like this:

enter image description here

In this example the map lineup has two children of type map. There might be more and there might be zero for other docs.

I'm trying to convert the lineup map of a DocumentSnapshot into a LineUp object generated by freezed.

This is my code so far:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:json_annotation/json_annotation.dart';
part 'line_up.freezed.dart';
part 'line_up.g.dart';

@freezed
abstract class LineUp with _$LineUp {
  const factory LineUp({
    required Map<String, dynamic> artistMap,
  }) = _LineUp;

  factory LineUp.fromDocumentSnapshot(DocumentSnapshot documentSnapshot) {
    final Map<String, dynamic> parsed = documentSnapshot.data()?["lineup"];
    print(parsed.toString()); //prints { p88U4b5lbAwouMVjjNZX: {trackId: 53, name: Name2}, fbei2rdwqBuMDTuFwY4m: {trackId: 23, name: Name1}}
    return LineUp.fromJson(parsed); //Exception thrown: 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast
  }
  factory LineUp.fromJson(Map<String, dynamic> json) => _$LineUpFromJson(json);
}

Obviously something is missing since nowhere name and trackId is defined in the freezed class.

Lara
  • 84
  • 1
  • 7
  • 30

1 Answers1

-1

I'm not sure about freezed, but you can do it manually so you get the hang of what freeze or any third party plugin is doing.

Create a class called lineup

Class LineUp {
String name;
String trackId;

factory LineUp.fromMap(Map<String, dynamic> map) {
    return LineUp(
      name: map['name'],
      trackId: map['trackId'])}
    }

Then, somewhere along your code where you want to create the object from the document snapshot,

List<LineUp> lineupList=[];
for (var item in documentSnapshot.data()?["lineup"].values){
lineupList.add(LineUp.fromMap(item));
}

print(lineupList[0].name); // should print the name of your first lineup item.
Huthaifa Muayyad
  • 11,321
  • 3
  • 17
  • 49
  • So as you can see in my screenshot below `lineup` there is another map `location` in this document (the whole doc describes an event). Would you suggest creating a `Location` object just like you created the `List` object and pass them as parameters for an `Event` object? I was actually hoping for an elegant way to have it all done at once. But if that's the way to do it I'll accept your answer – Lara Apr 04 '21 at 15:41
  • Do the same thing for it and expirement working with maps, and see how it goes, it's more fun coding. – Huthaifa Muayyad Apr 04 '21 at 15:53
  • Your example is missing the code of the freezed object of the document containing your lineup, provide it and I'll give you the elegant solution you are looking for. – Hikeland Apr 07 '21 at 16:15