Flutter/Firestore - 实时收听集合和子集合

时间:2020-12-24 23:33:54

标签: firebase flutter dart google-cloud-firestore

我有一个名为“reviews”的 firebase 集合,还有一个子集合“clients”。

我希望从 Firebase Firestore 实时获取与其所有者的所有评论,但在正确映射数据和返回侦听器的结果方面我有点迷茫。

这是“评论”模型:

class Review {
    final String reviewTitle;
    final String reviewContent;
    final String reviewCategory;
    final String reviewTimestamp;
    final int reviewVotesCount;
    final Client client;

    Review(
        {this.reviewTitle,
        this.reviewContent,
        this.reviewCategory,
        this.reviewTimestamp,
        this.reviewVotesCount,
        this.client});
}

这是服务类:

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

    List<Review> fetchAllThreads() {
    Review review;
    Client client;
    List<Thread> mReviewsList = new List<Review>();
    firestoreInstance.collection('reviews').snapshots().listen((result) {
        result.docs.forEach((result) {
             firestoreInstance
               .collection('reviews')
               .doc(result.id)
               .collection('clients')
               .get()
               .then((result) {/*here I get the result.data()*/});
        });
    });
}

问题 在我得到 result.data() 之后,我如何将它映射到我的模型,以便我可以将结果对象添加到 mReviewsList 然后返回 mReviewsList ?< /p>

1 个答案:

答案 0 :(得分:2)

您可以在 Review 类中添加工厂构造函数以从 Map 创建它,这同样适用于 Client

  factory Review.fromMap(Map<String, dynamic> map) {
    if (map == null) return null;
  
    return Review(
      reviewTitle: map['reviewTitle'],
      reviewContent: map['reviewContent'],
      reviewCategory: map['reviewCategory'],
      reviewTimestamp: map['reviewTimestamp'],
      reviewVotesCount: map['reviewVotesCount'],
      client: Client.fromMap(map['client']),
    );
  }

如果你使用的是 VS Code,'Dart Data Class Generator' 扩展可以派上用场,而且 pub.dev 中有多个代码生成包用于序列化和反序列化

现在代替您的评论,您可以这样做:

mReviewsList.add(Review.fromMap(result.data())); 

更新:

根据 Doug 的评论,如果您想将数据映射到模型并返回流,您可以创建一个辅助函数,如下所示:

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

要使用它,只需按如下方式调用它:

final stream = collectionStream<Review>(path: "reviews", builder: (data) => Review.fromMap(data));

如果你只想获取一次数据,你也可以为此创建一个辅助函数:

Future<List<T>> getDocuments<T>({
  String path,
  @required T builder(Map<String, dynamic> data),
}) async {
  final reference = FirebaseFirestore.instance.collection(path);
  final snapshots = await reference.get();
  final docs = snapshots.docs.map((doc) => builder(doc.data())).toList();
  return docs;
}

并以同样的方式调用它:

final reviews = getDocuments<Review>(path: "reviews", builder: (data) => Review.fromMap(data));
相关问题