Firebase Flatter Firestore查询2集合
问题已更新 如何查询2个集合?我有一个愿望列表集合,其中每个愿望列表文档如下所示:Firebase Flatter Firestore查询2集合,firebase,flutter,dart,google-cloud-firestore,Firebase,Flutter,Dart,Google Cloud Firestore,问题已更新 如何查询2个集合?我有一个愿望列表集合,其中每个愿望列表文档如下所示: documentID: "some-wishlist-id", modified: "1564061309920", productId: "2tqXaLUDy1IjxLafIu9O", userId: "0uM7Dt286JYK6q8iLFyF4tG9cK53" 以及一个产品集合,其中每个产品文档如下所示。wishlist集合中的productId将是产品集合中的documentID: documentID:
documentID: "some-wishlist-id",
modified: "1564061309920",
productId: "2tqXaLUDy1IjxLafIu9O",
userId: "0uM7Dt286JYK6q8iLFyF4tG9cK53"
以及一个产品集合,其中每个产品文档如下所示。wishlist集合中的productId将是产品集合中的documentID:
documentID: "2tqXaLUDy1IjxLafIu9O",
dateCreated: "1563820643577",
description: "This is a description for Product 9",
images: ["some_image.jpg"],
isNegotiable: true,
isSold: false,
rentPrice: 200,
sellPrice: 410,
title: "Product 9",
totalWishLists: 0,
userId: "0uM7Dt286JYK6q8iLFyF4tG9cK53"
注意:为了清楚起见,wishlist查询应该返回我需要迭代以检索产品的文档列表。
我不确定在这种情况下是否需要使用streams或futures,但到目前为止我已经做到了:
Future<Product> getProduct(String documentId) {
return Firestore.instance
.collection(APIPath.products())
.document(documentId)
.get()
.then((DocumentSnapshot ds) => Product.fromMap(ds.data));
}
Query getWishListByUser(userId) {
return Firestore.instance
.collection(APIPath.wishlists())
.where('userId', isEqualTo: userId);
}
Future<List<Product>> getProductsWishList(userId) async {
List<Product> _products = [];
await getWishListByUser(userId)
.snapshots()
.forEach((QuerySnapshot snapshot) {
snapshot.documents.forEach((DocumentSnapshot snapshot) async {
Map<String, dynamic> map = Map.from(snapshot.data);
map.addAll({
'documentID': snapshot.documentID,
});
WishList wishList = WishList.fromMap(map);
await getProduct(wishList.productId).then((Product product) {
print(product.title); // This is printing
_products.add(product);
});
});
});
// This is not printing
print(_products);
return _products;
}
Future-getProduct(字符串documentId){
返回Firestore.instance
.collection(APIPath.products())
.document(documentId)
.get()
.然后((DocumentSnapshot ds)=>Product.fromMap(ds.data));
}
查询getWishListByUser(用户ID){
返回Firestore.instance
.collection(APIPath.wishlists())
.where('userId',isEqualTo:userId);
}
未来的getProductsWishList(用户ID)异步{
列表_产品=[];
等待getWishListByUser(用户ID)
.快照()
.forEach((查询快照快照){
snapshot.documents.forEach((DocumentSnapshot snapshot)异步{
Map Map=Map.from(snapshot.data);
map.addAll({
“documentID”:snapshot.documentID,
});
WishList WishList=WishList.fromMap(地图);
等待getProduct(wishList.productId)。然后((产品){
打印(product.title);//这是打印
_产品。添加(产品);
});
});
});
//这不是印刷品
印刷品;
退货产品;
}
感谢使用任何数据库,您通常需要连接多个表中的数据以构建视图 在关系数据库中,通过使用JOIN子句,您可以使用一条语句从这些多个表中获取数据 但在Firebase(和许多其他NoSQL数据库)中,没有内置的方式来连接来自多个位置的数据。因此,您必须在代码中这样做 创建愿望列表模型:
class Wishlist {
Wishlist({
this.id,
this.modified,
this.productId,
this.userId
});
final String id;
final String modified;
final String productId;
final String userId;
Wishlist.fromMap(json)
: id = json['id'].toString(),
modified = json['modified'].toString(),
productId = json['productId'].toString(),
userId = json['userId'].toString();
}
在API文件中,执行以下操作:
final Firestore _fireStore = Firestore.instance;
getWishList(wishlistId) async {
return await _fireStore.collection('wishlists').document(wishlistId).get();
}
getProduct(productId) async {
return await _fireStore.collection('product').document(productId).get();
}
Future<List<Product>>getProductsWishList(wishlistId) async {
var _wishlists = null;
List<Product> _products = []; // I am assuming that you have product model like above
await getWishList(wishlistId).then((val) {
_wishlists = Wishlist.fromMap(val.data);
_wishlists.forEach((wish) {
await getProduct(wish.productId).then((product) {
_products.add(product));
});
});
});
return _products;
}
final Firestore\u Firestore=Firestore.instance;
getWishList(wishlistId)异步{
return wait_fireStore.collection('wishlists').document(wishlistId.get();
}
getProduct(productId)异步{
return wait_fireStore.collection('product').document(productId.get();
}
FutureGetProductsSwishList(wishlistId)异步{
var_wishlists=null;
列出_products=[];//我假设您有如上所述的产品模型
等待getWishList(wishlistId)。然后((val){
_wishlists=Wishlist.fromMap(val.data);
_愿望清单。forEach((愿望){
等待getProduct(wish.productId)。然后((product){
_产品。添加(产品));
});
});
});
退货产品;
}
上周末我找到了一个解决方案,但忘记发布了。我想我现在应该这样做,以防其他人有这个问题
我使用了StreamBuilder
和FutureBuilder
的组合。不确定是否有更好的答案,可能是合并多个流?但这对我很有效
return StreamBuilder<List<Wishlist>>(
stream: wishListStream(userId),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Wishlist> wishlists = snapshot.data;
if (wishlists.length > 0) {
return new GridView.builder(
scrollDirection: Axis.vertical,
itemCount: wishlists.length,
itemBuilder: (context, index) {
Future<Product> product =
getProduct(wishlists[index].productId);
return FutureBuilder(
future: product,
builder: (context, snapshot) {
if (snapshot.hasData) {
Product product = snapshot.data;
// Do something with product
} else {
return Container();
}
},
);
},
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
);
} else {
return Text('No products in your wishlist');
}
}
if (snapshot.hasError) {
print('WishlistPage - ${snapshot.error}');
return Center(child: Text('Some error occurred'));
}
return Center(child: CircularProgressIndicator());
},
);
返回StreamBuilder(
流:wishListStream(用户ID),
生成器:(上下文,快照){
if(snapshot.hasData){
列表愿望列表=snapshot.data;
如果(wishlists.length>0){
返回新的GridView.builder(
滚动方向:轴垂直,
itemCount:wishlists.length,
itemBuilder:(上下文,索引){
未来产品=
getProduct(愿望列表[index].productId);
回归未来建设者(
未来:产品,
生成器:(上下文,快照){
if(snapshot.hasData){
产品=快照.data;
//对产品做些什么
}否则{
返回容器();
}
},
);
},
gridDelegate:新SliverGridDelegateWithFixedCrossAxisCount(
交叉轴计数:2,
),
);
}否则{
返回文本(“您的愿望列表中没有产品”);
}
}
if(snapshot.hasError){
打印('WishlistPage-${snapshot.error}');
返回中心(子项:Text(“发生了一些错误”);
}
返回中心(子项:CircularProgressIndicator());
},
);
是否要在列表中呈现该数据?是指product中的一些字段和wishlist中的一些字段?@MuhammadNoman我只想返回wishlist中的产品。那么愿望清单上什么都没有。你有愿望清单吗?是的。我将在原始问题中添加documentID。检查以下答案谢谢,wishlist查询将返回wishlist文档列表,而不是单个wishlist文档wishlist查询如何返回wishlist文档列表?您正在查询id为(主键)的wishlist表,该表应返回一个文档。跨多个文档运行会不会延迟太多?会的,但您没有任何其他选项。因为它是NoSQL数据库