[英]Flutter & Firebase: Return list of collections
找不到有关此的任何信息,因为这里已经使用“listCollections()”或“getCollections()”的答案甚至不是有效的方法。
我有一个这样的数据库设置:
Layout: Collection -> Document -> Collection -> Documents
Example Data:
Stores -> UID -> StoreName1 ->
StoreName2 ->
StoreName3 ->
因此,鉴于我知道 Stores 和 UID,我应该能够轻松地返回上面的所有商店名称。 必须有一行代码会给我结果:StoreName1、StoreName2 和 StoreName3。
这是我所拥有的:
CollectionReference documents = (await Firestore.instance.collection('Stores').document(widget.currentUserUID). <---- now what? There is no getCollections, there is no listCollections. How can I return this information?
因此,在与下面的 Peter 讨论过这个问题后,我尝试通过一种调整后的方法来工作,但它看起来非常混乱。 有没有更好的方法来做到这一点? 感觉不对。 让我从新设计开始:
Layout: Collection -> Document -> Collection -> Documents
Example Data:
Stores -> UID -> StoresList -> Store1
store_name: 'My Place'
Store2
store_name: 'Bellagio'
Store3
store_name: 'Grand Hotel'
所以你可以看到上面的Store1、Store2和Store3是文档,它们有字段,其中一个是store_name。
我正在尝试向用户展示他们在其帐户下拥有的商店列表。 我必须这样做的方式,不知道每个用户可能想要经营多少家商店,如下
storeCount == 0 ? SizedBox()
:
storeCount == 1 ? Container(
child: uid == null ? LoadingAnimation() : StreamBuilder(
stream: Firestore.instance.collection('stores').document(uid).collection('StoresList').document('Store1').snapshots(),
builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData) {
return LoadingAnimationBasic();
}
if (snapshot.data.data == null) {
return LoadingAnimationBasic();
} else {
return ListView.builder(
shrinkWrap: true,
itemCount: 1,
itemBuilder: (context, index) =>
_buildStoresList(context, snapshot.data),
);
}
},
)) :
storeCount == 2 ? Container(
child: uid == null ? LoadingAnimationBasic() : StreamBuilder(
stream: Firestore.instance.collection('stores').document(uid).collection('StoresList').document('Store1').snapshots(),
builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData) {
return LoadingAnimationBasic();
}
if (snapshot.data.data == null) {
return LoadingAnimationBasic();
} else {
return ListView.builder(
shrinkWrap: true,
itemCount: 1,
itemBuilder: (context, index) =>
_buildStoresList(context, snapshot.data),
);
}
},
),
Container(
child: uid == null ? LoadingAnimationBasic() : StreamBuilder(
stream: Firestore.instance.collection('stores').document(uid).collection('StoresList').document('Store2').snapshots(),
builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData) {
return LoadingAnimationBasic();
}
if (snapshot.data.data == null) {
return LoadingAnimationBasic();
} else {
return ListView.builder(
shrinkWrap: true,
itemCount: 1,
itemBuilder: (context, index) =>
_buildStoresList(context, snapshot.data),
);
}
},
),
) : SizedBox(),
然后是_buildStoresList function:
Widget _buildStoresList(BuildContext context, DocumentSnapshot document) {
storeName = document['store_name'];
return Center(
child: Text(
storeName,
style: TextStyle(
fontFamily: 'Petita',
color: Colors.black,
fontSize: 60,
),
),
);
}
所以基本上,首先计算用户拥有多少个商店(通过在 initState() 期间使用 Future.delayed 解决方法计算 StoresList 集合中的文档数以正确填充它)。 一旦我有了商店的数量,我能看到从每个文档中获取数据的唯一方法就是使用可怕的嵌套 if 语句来完成上述操作。
我在这里做错了什么? 或者这是唯一的方法吗?
我想主要问题是关于这条线:
stream: Firestore.instance.collection('stores').document(uid).collection('StoresList').document('Store1').snapshots(),
我需要提供特定文档以便对字段进行快照。 如果有一条线来拍摄集合中所有文档的快照,而不是像这样一次只拍摄一个,效率会无限提高。 否则,如果用户想管理 200 家商店,这个“if 语句”嵌套将是疯狂的。
您需要将数据库更改为以下内容:
Stores (Collection) --> UID (Document) --> Stores (Collection) --> StoreName_1 (Document)
StoreName_2 (Document)
然后你可以这样做:
var documents = await Firestore.instance.collection('Stores').document(widget.currentUserUID).collection("Stores").getDocuments();
这将使您获得一个用户下的所有Stores
。
(代表问题作者发布答案,以便将其移至答案空间) 。
我已经解决了这个问题,它比我最初尝试的嵌套 if 语句要简单得多。
所以数据库布局完全相同,您只能从文档中提取数据,而不是 collections,因此请确保在构建数据库时牢记这一点。
您可以从这样的集合中返回所有文档:
Container(
child: StreamBuilder(
stream: Firestore.instance.collection('stores').document(uid).collection('StoresList').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return LoadingAnimationBasic(); //This is a custom animation, you can use SizedBox() or anything you like here.
}
if (snapshot.data == null) {
return LoadingAnimationBasic();
} else {
return ListView(
shrinkWrap: true,
children: _buildStoresList(snapshot), //Here we are chucking the whole collection snapshot into a ListView builder. This sends all the documents in the collection in this direction.
);
}
},
),
),
然后处理所有这些文档的 function 非常简单:
_buildStoresList(AsyncSnapshot<QuerySnapshot> snapshot) {
return snapshot.data.documents
.map((doc) => ListTile(
title: Center(child: Text(doc['store_name'])), //store_name is one of the fields inside my documents inside the collection on which I took the snapshots.
subtitle: Center(child: Text(doc['about'])) //about is another such field.
))
.toList();
}
而已。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.