Firebase 颤振和火基:基本结构问题

Firebase 颤振和火基:基本结构问题,firebase,flutter,dart,google-cloud-firestore,Firebase,Flutter,Dart,Google Cloud Firestore,在理解我应该如何使用Firebase时,在逻辑和结构上存在一些问题 我有一个数据库,目前看起来如下: 在我使用过的应用程序中: StreamBuilder( stream: Firestore.instance.collection('stores').snapshots(), builder: (context, snapshot) { <code here> } ), 然后是一个错误,因为您只能在文档集合中循环,而不能在文档集合中循环 因此,由于这种设计

在理解我应该如何使用Firebase时,在逻辑和结构上存在一些问题

我有一个数据库,目前看起来如下:

在我使用过的应用程序中:

StreamBuilder(
  stream: Firestore.instance.collection('stores').snapshots(),
  builder: (context, snapshot) {
    <code here>
   }
 ),
然后是一个错误,因为您只能在文档集合中循环,而不能在文档集合中循环

因此,由于这种设计根本不起作用,我想可能会在数据库中添加另一个多余的级别,使其类似:

Collection:
  - application name
  Document: 
    - Stores
      Collection:
         - UID of user
           Fields:
             - Datafield1
             - Datafield2
             - Datafield3
             - Datafield4
             - etc etc etc
试图迫使它符合一些有用的东西。但它也不允许您在Firebase中执行此操作,因为它只在文档上显示字段,而不在集合上显示字段

所以我的问题是,我如何使用这个产品只循环一组用户的数据?我相信这是对这一行的简单更改:

stream: Firestore.instance.collection('stores').snapshots(),
但是我在网上找不到任何关于这个的东西

编辑:@SenpaiLeo

之前我是这样返回数据的:

return ListView.builder(
  itemExtent: 500,
  itemCount: snapshot.data.documents.length,
  itemBuilder: (context, index) =>
      _buildListRows(context, snapshot.data.documents[index]),
);
然后在buildListRows中:

Widget _buildListRows(BuildContext context, DocumentSnapshot document) {
...
  Container(
      child: TextField(
        controller: _storeNameController,
        decoration: InputDecoration(
           border: OutlineInputBorder(),
              hintText: document['store_name'],
           ),
        ),
    ),
    ...
因此,现在我可能已经根据您的建议更改了参考,现在:

document['store_name']
这是不正确的引用吗

Stream<QuerySnapshot> stream = Firestore.instance.collection('stores').where('uid', isEqualTo: uid).snapshots();
但我建议先听快照更改,然后更新所需的变量。

如果您使用此选项:

Collection:
  - Stores
     Document:
        - UID of user
         Collection:
            - Datafield1
            - Datafield2
            - Datafield3
            - Datafield4
            - etc etc etc
然后做:

Firestore.instance.collection('stores').document(uid).snapshots()
那么上面应该只获取uid文档中的数据,而不会获取子集合。如果要访问一个用户的子集合内的数据,请使用以下命令:

Firestore.instance.collection('stores').document(uid).collection('userStore').snapshots()
这将获取子集合userStore中的所有文档

解决方案:

child: StreamBuilder(
    stream: Firestore.instance.collection('stores').document(currentUserUID).snapshots(),
    builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
    if (snapshot.hasData) {
       return ListView.builder(
           shrinkWrap: true,
           itemCount: snapshot.data.data.length,
           itemBuilder: (context, index) =>
               _buildListRows(context, snapshot.data),
           );


Widget _buildListRows(BuildContext context, DocumentSnapshot document) {
return Container(
  height: MediaQuery.of(context).size.height * 0.8,
  child: ListView(
    children: <Widget>[
      Row(
        children: <Widget>[
          Padding(
            padding: EdgeInsets.fromLTRB(10, 0, 50, 0),
            child: Text(
              'Business Name',
              style: Theme
                  .of(context)
                  .textTheme
                  .body2,
            ),
          ),
          Container(
            height: 50,
            width: 200,
            padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
            child: TextField(
              controller: _storeNameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                hintText: document['store_name'],
              ),
            ),
          ),
        ],
      ),
此Firestore.instance.collection'stores.documentcurrentUserUID.snapshots将获取当前用户的文档,然后要访问它,请执行snapshot.data.data[location]

以问题作者的名义发布解决方案,以便将其移动到答案空间

这对我有用:

child: StreamBuilder(
    stream: Firestore.instance.collection('stores').document(currentUserUID).snapshots(),
    builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
    if (snapshot.hasData) {
       return ListView.builder(
           shrinkWrap: true,
           itemCount: snapshot.data.data.length,
           itemBuilder: (context, index) =>
               _buildListRows(context, snapshot.data),
           );


Widget _buildListRows(BuildContext context, DocumentSnapshot document) {
return Container(
  height: MediaQuery.of(context).size.height * 0.8,
  child: ListView(
    children: <Widget>[
      Row(
        children: <Widget>[
          Padding(
            padding: EdgeInsets.fromLTRB(10, 0, 50, 0),
            child: Text(
              'Business Name',
              style: Theme
                  .of(context)
                  .textTheme
                  .body2,
            ),
          ),
          Container(
            height: 50,
            width: 200,
            padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
            child: TextField(
              controller: _storeNameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                hintText: document['store_name'],
              ),
            ),
          ),
        ],
      ),

再次感谢彼得·哈达德在这方面的工作

你在这里得到了什么流:Firestore.instance.collection'stores'.documentuid.snapshots,?一个错误,指出文档引用必须有偶数个段,当我在线查找时,这意味着你根本无法在文档级别进行快照,您只能在集合级别执行此操作。您也可以在文档级别执行快照。你能确认你试图查询的uid存在于stores集合中吗?是的,它确实匹配,我已经设置了打印捕获,在应用程序的各个阶段向我显示uid,每次都是正确的。该应用程序还成功地从Firebase提取数据,只是问题在于它提取了所有数据,而不是当前用户。谢谢Peter。我不能像你建议的那样设置数据库,因为它根本不允许。在Firebase中,一旦进入文档级别,下一部分就不是集合。我可能写错了,我会编辑它。它将不允许集合中的数据字段,而只允许文档中的数据字段。我现在更新这个问题,因为我在尝试你的建议之前没有意识到这一点。这比我想象的还要糟糕。在firebase中,你有一个集合,在每个集合中你有文档,然后在每个文档中你可以有文档的子集合或数据。如果你想获取uid文档的数据,那么你可以使用documentuid来获取。如果您在该文档中没有数据,那么您将什么也得不到。如果要获取该文档下的子集合中的数据。然后你就按照答案做。例如:子集合userData将包含包含您可以检索的数据的文档。您也可以对文档调用snapshot检查这是针对js的,但在我调用时应用于js。文档级别的快照,如:stream:Firestore.instance.collection'stores.documentuid.snapshots,我得到以下错误。文档引用的段数必须为偶数。谷歌告诉我这是因为它不可能做到这一点。这让我有点不知所措!它至少不会产生任何错误,所以这很重要。但它不会在我的应用程序中返回任何数据。以前我得到的数据是。。让我更新我的问题以适当地回答你。
child: StreamBuilder(
    stream: Firestore.instance.collection('stores').document(currentUserUID).snapshots(),
    builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
    if (snapshot.hasData) {
       return ListView.builder(
           shrinkWrap: true,
           itemCount: snapshot.data.data.length,
           itemBuilder: (context, index) =>
               _buildListRows(context, snapshot.data),
           );


Widget _buildListRows(BuildContext context, DocumentSnapshot document) {
return Container(
  height: MediaQuery.of(context).size.height * 0.8,
  child: ListView(
    children: <Widget>[
      Row(
        children: <Widget>[
          Padding(
            padding: EdgeInsets.fromLTRB(10, 0, 50, 0),
            child: Text(
              'Business Name',
              style: Theme
                  .of(context)
                  .textTheme
                  .body2,
            ),
          ),
          Container(
            height: 50,
            width: 200,
            padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
            child: TextField(
              controller: _storeNameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                hintText: document['store_name'],
              ),
            ),
          ),
        ],
      ),