Dart 如何在项目生成器中显示Firestore中的列表

Dart 如何在项目生成器中显示Firestore中的列表,dart,flutter,google-cloud-firestore,Dart,Flutter,Google Cloud Firestore,下面的getComponents()方法从firestore返回一个列表 Future getIngredients() async { return Firestore.instance .collection('ingredients') .where("name", isEqualTo: widget.dish_name.toString().toLowerCase()).getDocuments(); } 现在,我想在下面的项目生成器中显示此

下面的getComponents()方法从firestore返回一个列表

Future getIngredients() async {
    return Firestore.instance
        .collection('ingredients')
        .where("name", isEqualTo: widget.dish_name.toString().toLowerCase()).getDocuments();
  }
现在,我想在下面的项目生成器中显示此列表:

 new ListView.builder(
                  itemExtent: 90,
                  itemCount: snapshot.data.length,
                  itemBuilder: (BuildContext context, int index) {
                      return SingleIngredient(
                        ingredient_name: snapshot.data[index].ingredients,
                      );
                  });
我收到以下错误消息:

_FutureBuilderState#7cbda):I/flatter(12164):类“QuerySnapshot”没有实例getter“length”。I/颤振(12164): 接收者:“QuerySnapshot”I/flatter(12164)的实例:已尝试 呼叫:长度

这是我火炉店的结构。我正在获取配料表:

更新 我已经更新了代码,但我只得到了配料表中的第一项(即洋葱)。我希望itembuilder构建列表中的每个项目,因为我试图显示图像和成分列表。这就是SingleComponent小部件所做的。那么,我如何逐一循环浏览每个列表呢

 Widget build(BuildContext context) {
    return Container(
      child: FutureBuilder(
          future: getIngredients(),
          builder: (context, AsyncSnapshot snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                itemCount: snapshot.data.documents.length,
                itemBuilder: (context, index) {
                  DocumentSnapshot user = snapshot.data.documents[index];

                  return SingleIngredient(
                    // Access the fields as defined in FireStore
                    ingredient_name: user.data['ingredients'][index].toString(),
                  );
                },
              );
            } else if (snapshot.connectionState == ConnectionState.done &&
                !snapshot.hasData) {
              // Handle no data
              return Center(
                child: Text("No users found."),
              );
            } else {
              // Still loading
              return CircularProgressIndicator();
            }
          }),
    );
  }
}

Dart不知道您从未来返回的类型,因此它将其解释为一个动态对象,上面没有长度获取程序。改变你的方法

Future getIngredients() async {
return Firestore.instance
    .collection('ingredients')
    .where("name", isEqualTo: widget.dish_name.toString().toLowerCase()).getDocuments();
}

Future<List<YourType>> getIngredients() async {
return Firestore.instance
    .collection('ingredients')
    .where("name", isEqualTo: widget.dish_name.toString().toLowerCase()).getDocuments();
Future getComponents()异步{
返回Firestore.instance
.收集(‘成分’)
.where(“name”,isEqualTo:widget.dish_name.toString().toLowerCase()).getDocuments();
}


其中YourType是从getDocuments()函数返回的类型。您可能还需要对其执行toList()。

下面是一个使用
StreamBuilder
的示例,我从集合中检索所有文档,并构建一个
列表视图来显示它们:

Widget buildUserList(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
    if (snapshot.hasData) {
        return ListView.builder(
            itemCount: snapshot.data.documents.length,
            itemBuilder: (context, index) {
                DocumentSnapshot user = snapshot.data.documents[index];

                return ListTile(
                    // Access the fields as defined in FireStore
                    title: Text(user.data['firstName']),
                    subtitle: Text(user.data['lastName']),
                );
            },
        );
    } else if (snapshot.connectionState == ConnectionState.done && !snapshot.hasData {
        // Handle no data
        return Center(
            child: Text("No users found."),
        );
    } else {
        // Still loading
        return CircularProgressIndicator();
    }
}

正文:StreamBuilder(
流:Firestore.instance
.collection(‘ups’)
.其中(‘pc’,
isEqualTo:widget.post.data[“pc”])
.snapshots(),
生成器:(上下文,快照){
如果(!snapshot.hasData){
返回中心(
子项:文本(“加载…”),
);
}否则{
最终ups=snapshot.data.documents;
列表stateWidget=[];
用于(ups中的var消息){
final stateText=message.data['state'];
//最终状态集合=文本(“$stateText”);
stateWidget.add(stateText);
}在这里输入代码
返回列表视图(
儿童:stateWidget
.map((数据)=>ListTile(`在此处输入代码`
标题:文本(数据),
onTap:()=>{u selectedItem(数据)})
.toList(),`在此处输入代码`
)

我在实施您的更改时遇到以下错误:返回类型“Future”不是该方法定义的“Future”getIngredients@bangbang您返回的是列表getDocuments返回的是什么?请查看随附的firestore文档结构。我返回的是成分列表(字符串)。如果我将查询更改为以下内容:Future GetComponents()async{return Firestore.instance.collection('Components')。其中(“名称”,isEqualTo:widget.dish_name.toString().toLowerCase()).snapshots().listen((数据)=>data.documents.forEach((文档)=>print(文档[“Components”);)我能够得到一个成分列表。我只是不知道如何在Widget中显示它。您提供的示例将打印单值字段。我想打印并存储一个数组字段。我该怎么做?您可以从生成器返回任何小部件来显示您想要的任何类型的数据。它不必是
ListView
中的所有字段ode>DocumentSnapshot.data
动态的
,因此您可以执行类似于
List=snapshot.data.documents[index].data['myListKey'];
的操作来检索值。这两种方法实际上都可以工作。如果您想使用
getDocuments()
您需要一个
FutureBuilder
,因为它返回一个
Future
使其返回一个
确切地说,我正在使用FututeBuilder,但我如何在不使用streambuilder的情况下显示结果?能否请您提供一个从firestore访问数组字段的示例?它们的使用方式基本相同。更新的答案您必须使用
快照.data.documents
来访问文档查询的长度,因此要获取长度,它将是
snapshot.data.documents.length
.Hi@miriam,能否缩进代码以使其更具可读性。一些右括号似乎缺失,并且
此处输入代码
字符串似乎错误。
Scaffold(
    body: StreamBuilder(
        stream:
            Firestore.instance.collection('users').snapshots(),
        builder: buildUserList,
    )
)
Scaffold(
    body: FutureBuilder(
        future:
            Firestore.instance.collection('users').getDocuments(),
        builder: buildUserList,
    )
)
body: StreamBuilder(
stream: Firestore.instance
    .collection('ups')
.where('pc',
isEqualTo: widget.post.data["pc"])
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: Text("Loading..."),
);
} else {
final ups = snapshot.data.documents;
List<String> stateWidget = [];
for (var message in ups) {
final stateText = message.data['state'];
// final stateCollection = Text('$stateText');
stateWidget.add(stateText);
}enter code here
return  ListView(
children: stateWidget
    .map((data) => ListTile(`enter code here`
title: Text(data),
onTap: () => {_selectedItem(data)}))
    .toList(),`enter code here`
)