如何使用Flutter从Firestore中的collectionGroup中查询数据

问题描述 投票:0回答:1

对于我正在Flutter中构建的应用程序,我试图从Firestore检索登录用户在不同日期的保留时隙列表。我到达了可以在给定日期检索保留时隙的时间(通过对该日期进行硬编码并将其传递给futurebuilder),但是当我尝试从collectionGroup检索数据时,listview保持为空。现在,作为Flutter的初学者,我发现很难理解如何处理collectionGroup查询,因此,我们将不胜感激!

关于我的数据库结构的快速概述,我在github上包括了两张图片:

图片1:https://github.com/winckles/rooster/blob/master/Schermafbeelding%202019-11-10%20om%2020.08.20.png?raw=true

图片2:https://github.com/winckles/rooster/blob/master/Schermafbeelding%202019-11-10%20om%2020.08.43.png?raw=true

下面我包括了我的futurebuilder和listview构建器

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class TimesTest extends StatefulWidget {
  @override
  _TimesTestState createState() => _TimesTestState();
}

class _TimesTestState extends State<TimesTest> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: MyFutureBuilder('2019-11-10'),
      ),
    );
  }
}

class MyFutureBuilder extends StatelessWidget {
  final String date;
  MyFutureBuilder(this.date);

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: MyTimes().getMyTimes('${loggedInUser.email}', date),
      builder: (context, AsyncSnapshot snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(
            child: CircularProgressIndicator(
              backgroundColor: Colors.lightBlueAccent,
            ),
          );
        } else if (snapshot.hasData) {
          return ListView.builder(
              padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
              itemCount: snapshot.data.documents.length,
              itemBuilder: (BuildContext context, int index) {
                DocumentSnapshot user = snapshot.data.documents[index];
                return Padding(
                  padding: EdgeInsets.symmetric(
                    horizontal: 7.0,
                    vertical: 3.0,
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Card(
                        color: Colors.white,
                        child: Container(
                          child: ListTile(
                            onTap: () {},
                            title: Text(
                              user.data['hour'],
                              style: TextStyle(
                                color: Colors.grey[900],
                              ),
                            ),
                            subtitle: Text(
                              user.data['reserved'],
                              style: TextStyle(
                                color: Colors.grey[900],
                              ),
                            ),
                            leading: Icon(
                              Icons.access_time,
                              color: Colors.grey[900],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                );
              });
        } else if (snapshot.connectionState == ConnectionState.done &&
            !snapshot.hasData) {
          return Center(
            child: Text('No times found'),
          );
        } else {
          return Center(
            child: Text('No times found'),
          );
        }
      },
    );
  }
}

这就是我从Firestore获取数据的方式。

import 'package:cloud_firestore/cloud_firestore.dart';

class MyTimes {
  Future getMyTimes(String reserved, String date) async {
    return Firestore.instance
        .collection('days')
        .document(date)
        .collection('hours')
        .where('reserved', isEqualTo: reserved)
        .getDocuments();
  }
}

//I have also tried this:
//class MyTimes {
//  Future getMyTimes(String reserved) async {
//    return Firestore()
//        .collectionGroup('hours')
//        .where('reserved', isEqualTo: reserved)
//        .getDocuments();
//  }
//}

我创建了一个索引,其集合ID为'hours',集合范围为'collectionGroup',现在我的安全规则如下:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }

    match /{path=**}/hours/{document}{
    allow read, write;
    }
  }
}

我已经花了很多小时试图找出答案,所以真的很感谢任何有用的东西!

firebase flutter dart google-cloud-firestore
1个回答
0
投票

在您的示例中,您没有使用collectionGroup查询。您需要对非保留的插槽执行类似Firestore.instance.collectionGroup('hours').where('reserved', isEqualTo: '').getDocuments();的操作。

因此,保留该插槽后,您将在002文档中存储什么?而且为什么不为状态使用诸如布尔值的显式类型呢?这也使它更容易。

© www.soinside.com 2019 - 2024. All rights reserved.