从 Stream 检索快照时,Flutter/Firestore 返回类型 List<Review> 不是“Map<String, dynamic>”类型的子类型

Posted

技术标签:

【中文标题】从 Stream 检索快照时,Flutter/Firestore 返回类型 List<Review> 不是“Map<String, dynamic>”类型的子类型【英文标题】:Flutter/Firestore returns type List<Review> is not a subtype of type 'Map<String, dynamic>' when retrieving snapshots from Stream 【发布时间】:2021-04-03 12:02:50 【问题描述】:

我正在尝试使用 firestore 实时数据库检索带有子集合的集合并在 ListView 中显示结果,但我得到了type List&lt;Review&gt; is not a subtype of type 'Map&lt;String, dynamic&gt;',但我无法绕过它。

问题我应该改变什么才能正确返回所需的结果?

这是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.dartclient.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 子集合为空! Stream&lt;List&lt;T&gt;&gt; reviewsCollectionStream&lt;T&gt;(...) 有什么问题吗?

这就是我所做的: 在reviews_page.dartitemBuilder 内部:

而不是

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的子集合

【问题讨论】:

【参考方案1】:

Firestore 快照don't include subcollections

如果您想要子集合数据,则必须使用您提前知道的子集合名称进行新查询

另外,请参阅此link 以获取有关如何获取子集合数据的参考

【讨论】:

以上是关于从 Stream 检索快照时,Flutter/Firestore 返回类型 List<Review> 不是“Map<String, dynamic>”类型的子类型的主要内容,如果未能解决你的问题,请参考以下文章

如何从地点选择器活动中检索地图快照?

检索 Firebase 快照导致加载验证错误

尽管通过 Stream 发送,StreamBuilder 的快照没有数据

Firebase 快照中的 Stream<List<Object>> 是不是会在节点的每次更改时返回整个节点?扑

如何检索推送通知php的ck.pem文件

Swift不检索Firebase值(返回值为NSNull)