Flutter / Firestore возвращает тип List ‹Review› не является подтипом типа «Map‹ String, dynamic ›» при получении снимков из Stream.

Я пытаюсь получить коллекцию с ее под-коллекцией, используя базу данных в реальном времени firestore и отображая результаты в ListView, но вместо этого я получил type List<Review> is not a subtype of type 'Map<String, dynamic>', и я не мог обойти его.

Вопрос Что мне нужно изменить, чтобы он возвращал нужные результаты правильно?

Это reviews_service.dart:

class ReviewsService {
  var currentUser = FirebaseAuth.instance.currentUser;
  var firestoreInstance = FirebaseFirestore.instance;

  Stream<List<T>> reviewsCollectionStream<T>({
    @required String path,
    @required T builder(Map<String, dynamic> data),
  }) {
    final reference = firestoreInstance.collection(path);
    final snapshots = reference.snapshots();
    return snapshots.map((snapshot) =>
        snapshot.docs.map((snapshot) => builder(snapshot.data())).toList());
}

Это мои классы моделей review.dart и client.dart.

class Review {
  final String reviewTitle;
  final String reviewContent;
  final Client owner;

  Review(
    {this.reviewTitle,
    this.reviewContent,
    this.owner});

  factory Review.fromMap(Map<String, dynamic> map) {
    if (map == null) return null;

    return Review(
      reviewTitle: map['revieewTitle'],
      reviewContent: map['reviewContent'],
      owner: Client.fromMap(map['owner']),
    );
  }
}

class Client {
  final String clientUID;
  final String clientEmail;
  final String clientName;

  Client({this.clientUID, this.clientEmail, this.clientName});

  factory Client.fromMap(Map<String, dynamic> map) {
    if (map == null) return null;

    return EndUser(
      clientUID: map['clientId'],
      clientEmail: map['clientEmail'],
      clientDisplayName: map['clientName'],
    );
  }
}

Здесь я получаю данные и отображаю их в Listview reviews_page.dart:

class _ReviewsPageState extends State<ReviewsPage> {
  final reviews = _mReviewService.reviewssCollectionStream(path: "reviews", builder: (data) => Review.fromMap(data));
  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Container(
        child: StreamBuilder<Object>(
           stream: reviews,
           builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                  controller: _scrollController,
                  itemBuilder: (BuildContext context, int index) {
                    Review rev = new Review(
                        reviewTitle: (snapshot.data as Map)["reviewTitle"][index].toString(),
                        reviewContent: (snapshot.data as Map)["reviewContent"][index].toString(),                      
                        owner: (snapshot.data as Map)["reviewOwner"][index]);
                    return Review(review: rev,);
                  },
               );
              } else {return Center(child: Text('there are no reviews'));}
            }),
      ),
    );
  }
}

ОБНОВЛЕНИЕ. Я начал работать. Получение выполняется правильно. Моя единственная проблема заключается в том, что подколлекция Client имеет значение NULL! что-то не так с Stream<List<T>> reviewsCollectionStream<T>({...})?

Вот что я сделал: в reviews_page.dart и внутри itemBuilder:

вместо того

Review rev = new Review(
                reviewTitle: (snapshot.data as Map)["reviewTitle"][index].toString(),
                reviewContent: (snapshot.data as Map)["reviewContent"][index].toString(),                      
                owner: (snapshot.data as Map)["reviewOwner"][index]);

Восстановил as List:

//only one line that's all what it takes
Review rev = (snapshot.data as List)[index]; 

но я все еще не могу получить вложенную коллекцию clients


person Thorvald Olavsen    schedule 25.12.2020    source источник


Ответы (1)


Снимки состояния Firestore не включают вложенные коллекции

Если вам нужны данные подколлекции, вам нужно будет сделать новый запрос, используя имя подколлекции, которое вы знаете заранее.

Также см. ссылка для справки о том, как получить данные подколлекции

person Jose V    schedule 28.12.2020