Flutter Dart - документ Firestore с вложенными картами в класс данных с замороженными

В Firestore мои документы структурированы следующим образом:

введите описание изображения здесь

В этом примере карта lineup имеет двух дочерних элементов типа map. Их может быть больше, а для других документов может быть ноль.

Я пытаюсь преобразовать lineup карту DocumentSnapshot в объект LineUp, созданный замороженным.

Это мой код на данный момент:

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);
}

Очевидно, чего-то не хватает, поскольку в замороженном классе нигде не определены name и trackId.


person Lara    schedule 04.04.2021    source источник


Ответы (1)


Я не уверен в зависании, но вы можете сделать это вручную, чтобы понять, что делает замораживание или какой-либо сторонний плагин.

Создайте класс под названием lineup

Class LineUp {
String name;
String trackId;

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

Затем где-нибудь в коде, где вы хотите создать объект из моментального снимка документа,

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.
person Huthaifa Muayyad    schedule 04.04.2021
comment
Итак, как вы можете видеть на моем снимке экрана ниже lineup, в этом документе есть еще одна карта location (весь документ описывает событие). Не могли бы вы предложить создать объект Location так же, как вы создали объект List<LineUp>, и передать их в качестве параметров для объекта Event? На самом деле я надеялся на элегантный способ сделать все сразу. Но если это так, я приму твой ответ - person Lara; 04.04.2021
comment
Проделайте то же самое с ним и с истечением срока, работая с картами, и посмотрите, как оно пойдет, это веселее кодировать. - person Huthaifa Muayyad; 04.04.2021
comment
В вашем примере отсутствует код замороженного объекта документа, содержащего вашу линейку, предоставьте его, и я дам вам элегантное решение, которое вы ищете. - person Hikeland; 07.04.2021