从Firebase Firestore筛选数据

从Firebase Firestore筛选数据,firebase,flutter,google-cloud-firestore,Firebase,Flutter,Google Cloud Firestore,我在文档中有一个名为“category”的字段,在“category”中有6种不同类型的值(1-6)。我想在不同的屏幕上显示每个值的文档。因此,所有值为2的“类别”字段都应该显示在屏幕2上。我怎样才能让它工作呢 Widget build(BuildContext context) { return FutureBuilder( future: FirebaseAuth.instance.currentUser(), builder: (ctx, futur

我在文档中有一个名为“category”的字段,在“category”中有6种不同类型的值(1-6)。我想在不同的屏幕上显示每个值的文档。因此,所有值为2的“类别”字段都应该显示在屏幕2上。我怎样才能让它工作呢

Widget build(BuildContext context) {
    return FutureBuilder(
        future: FirebaseAuth.instance.currentUser(),
        builder: (ctx, futureSnapshot) {
          if (futureSnapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: const CircularProgressIndicator(),
            );
          }
          return StreamBuilder(
              stream: Firestore.instance
              .collection('facts')
              .orderBy('category')
              .where('category', isEqualTo: '1')
              .where('category', isEqualTo: '2')
              .where('category', isEqualTo: '3')
              .where('category', isEqualTo: '4')
              .where('category', isEqualTo: '5')
              .where('category', isEqualTo: '6')
              .snapshots(),

              builder: (ctx, snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return Center(
                    child: CircularProgressIndicator(
                      valueColor: AlwaysStoppedAnimation<Color>(
                        Theme.of(context).colorScheme.deepOrange,
                      ),
                    ),
                  );
                }

                final factsDocs = snapshot.data.documents;
                return Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: AssetImage("assets/facts_bg.jpg"),
                      fit: BoxFit.cover,
                    ),
                  ),
                  child: Scaffold(
                    backgroundColor: Colors.transparent,
                    body: ListView.builder(
                      padding: const EdgeInsets.symmetric(
                          horizontal: 10, vertical: 10),
                      itemCount: factsDocs.length,
                      itemBuilder: (ctx, index) =>
                          _factsList(context, factsDocs[index]),
                    ),
                  ),
                );
              });
        });
  }

  Widget _factsList(BuildContext context, DocumentSnapshot document) {
    return Container(
      child: Card(
        margin: const EdgeInsets.only(bottom: 16),
        elevation: 6,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        color: Colors.white.withOpacity(0.9),
        child: Column(
          children: [
            Column(
              children: [
                Container(
                  width: MediaQuery.of(context).size.width,
                  height: 120,
                  child: Column(
                    children: [
                      Padding(
                        padding: const EdgeInsets.only(top: 8),
                        child: ListTile(
                          title: Container(
                            child: Text(
                              document['title'] == null
                                  ? ''
                                  : document['title'],
                              style: whiteH1Txt,
                            ),
                          ),
                          subtitle: Padding(
                            padding: const EdgeInsets.only(top: 8),
                            child: Text(
                              document['category'] == null
                                  ? ''
                                  : document['category'],
                              style: whiteSubTxt,
                            ),
                          ),

小部件构建(构建上下文){
回归未来建设者(
future:FirebaseAuth.instance.currentUser(),
建筑商:(ctx,未来快照){
if(futureSnapshot.connectionState==connectionState.waiting){
返回常数中心(
子对象:常量循环ProgressIndicator(),
);
}
返回流生成器(
流:Firestore.instance
.collection(“事实”)
.orderBy('类别')
.where('category',isEqualTo:'1')
.where('category',isEqualTo:'2')
.其中('category',isEqualTo:'3')
.where('category',isEqualTo:'4')
.其中('category',isEqualTo:'5')
.where('category',isEqualTo:'6')
.snapshots(),
生成器:(ctx,快照){
if(snapshot.connectionState==connectionState.waiting){
返回中心(
子对象:循环压缩机指示器(
valueColor:始终停止动画(
Theme.of(context).colorScheme.deepOrange,
),
),
);
}
最终事实DOCS=snapshot.data.documents;
返回容器(
装饰:盒子装饰(
图像:装饰图像(
图片:资产评估(“资产/事实”\u bg.jpg”),
适合:BoxFit.cover,
),
),
孩子:脚手架(
背景颜色:颜色。透明,
正文:ListView.builder(
填充:const EdgeInsets.symmetric(
水平:10,垂直:10),
itemCount:factsDocs.length,
itemBuilder:(ctx,索引)=>
_factsList(上下文,factsDocs[索引]),
),
),
);
});
});
}
Widget\u factsList(构建上下文上下文、文档快照文档){
返回容器(
孩子:卡片(
边距:仅限常量边集(底部:16),
标高:6,
形状:RoundedRectangleBorder(borderRadius:borderRadius.circular(12)),
颜色:颜色。白色。不透明度(0.9),
子:列(
儿童:[
纵队(
儿童:[
容器(
宽度:MediaQuery.of(context).size.width,
身高:120,
子:列(
儿童:[
填充物(
填充:仅限常量边集(顶部:8),
孩子:ListTile(
标题:集装箱(
子:文本(
文档['title']==null
? ''
:文件['title'],
样式:whiteH1Txt,
),
),
字幕:填充(
填充:仅限常量边集(顶部:8),
子:文本(
文档['category']==null
? ''
:文件['category'],
样式:whiteSubTxt,
),
),

执行此查询的方式:

stream: Firestore.instance
    .collection('facts')
    .orderBy('category')
    .where('category', isEqualTo: '1')
    .where('category', isEqualTo: '2')
    .where('category', isEqualTo: '3')
    .where('category', isEqualTo: '4')
    .where('category', isEqualTo: '5')
    .where('category', isEqualTo: '6')
保证返回0个文档。Firestore查询将逻辑AND应用于每个where子句。此查询所做的是询问类别为1、2和3等的文档,您可以看到这是不可能的

如果需要包含每个类别的逻辑OR,可以改用WHERE查询:

stream: Firestore.instance
    .collection('facts')
    .orderBy('category')
    .where('category', whereIn: ['1', '2', '3', '4', '5', '6'])

您的代码必须查看每个文档,以查看它来自哪个类别,并决定如何处理它。

如何在新屏幕上显示某个类别的值?是否有您尝试过的方法没有达到预期效果?这听起来与正确查询完全不同。