itemcount中的snapshot.data.length不起作用:“在null上调用了getter'length'

时间:2019-01-24 11:45:45

标签: dart flutter google-cloud-firestore

我正在尝试使用以下代码从firestore中获取文档:

 Future getCategories() async {
    var firestore = Firestore.instance;
    QuerySnapshot qn = await firestore.collection("categories").getDocuments();
    return qn.documents;
  }

 @override
  Widget build(BuildContext context) {
    return Container(
      child:FutureBuilder(
        future:getCategories(),
        builder:(context, snapshot){
          if(snapshot.connectionState == ConnectionState.waiting){
            return Center(
              child:Text("Loading...")
            );
         }
         else
         {
           return GridView.builder(
             itemCount: snapshot.data.length,
             gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
                 crossAxisSpacing: 6.0, mainAxisSpacing: 6.0, crossAxisCount: 2),
              itemBuilder: (BuildContext context, int index) {
                return SingleCategory(
                  category_name:  snapshot.data[index].data["title"],
                  category_picture: snapshot.data[index].data["picture"],
                );
              }
           );
         }
        }
      )
    );

运行代码时,出现以下错误:

  

I / flutter(7555):W小部件库引起的异常提示   ╞═════════════════════════════════════════════════ ══════════我/扑   (7555):引发了以下NoSuchMethodError构建   FutureBuilder(脏,状态:I / flutter(7555):   _FutureBuilderState#c3e7b):I / flutter(7555):在null上调用了getter'length'。 I / flutter(7555):接收者:null   I / flutter(7555):尝试调用:长度I / flutter(7555):I / flutter   (7555):引发异常时,这是堆栈:I / flutter   (7555):#0 Object.noSuchMethod   (dart:core / runtime / libobject_patch.dart:50:5)

任何人都可以帮助我。

5 个答案:

答案 0 :(得分:1)

我们在评论中发现,您正在使用auth规则,该规则拒绝对所有请求的访问:

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

我认为您想编写类似这样的内容(只读模式):

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
       allow read;
       allow write: if false;
    }
  }
}

尝试此规则

答案 1 :(得分:1)

您应该在FutureBuilder小部件中添加initialData属性,并将其设置为[]空列表。例如:

FutureBuilder(  // only add initialData: []
    initilData: [],  // this is vital to get rid of null length error
    future:getCategories(),
    builder:(context, snapshot){
      if(snapshot.connectionState == ConnectionState.waiting){
        return Center(
          child:Text("Loading...")
        );
     } // and same code goes below

因此,我们的主要目的是通过为空数组添加initialData属性来防止空长度错误,从而解决了我们的问题。 这是此属性的正式定义---

将用于创建提供的快照的数据,直到 非空的未来已经完成。 我们还可以添加一些加载小部件以不向用户显示空白屏幕。

我们可以添加一个条件“当快照包含等于空数组(或data.length == 0)的数据时,则显示加载小部件,否则显示列表”。

答案 2 :(得分:1)

试试这个:

 future: getData(),
              builder: (context, AsyncSnapshot<List<User>> snapshot)

答案 3 :(得分:0)

最简单的方法是使用快照的hasData参数。

if (snapshot.hasData) { return GridViewBuilder(...);} 

答案 4 :(得分:0)

我有同样的问题尝试使用它。

 builder:(ctx, AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot)

如果您需要文档的长度,请使用 listView 的 itemCount 的完整 StreamBuilder 代码

StreamBuilder(
        stream: FirebaseFirestore.instance.collection('categories').snapshots(),
        builder:
            (ctx, AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
          return ListView.builder(
              itemCount: snapshot.data.docs.length,
              itemBuilder: (ctx, index) => Text('sample'));
        });