我有一个名为“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>
答案 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));