Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

snapshot.data.length in the itemcount does not work: "The getter 'length' was called on null"

I am trying to fetch documents from firestore with the following code:

 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"],
                );
              }
           );
         }
        }
      )
    );

When I run the code, I get the following error:

I/flutter ( 7555): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ I/flutter ( 7555): The following NoSuchMethodError was thrown building FutureBuilder(dirty, state: I/flutter ( 7555): _FutureBuilderState#c3e7b): I/flutter ( 7555): The getter 'length' was called on null. I/flutter ( 7555): Receiver: null I/flutter ( 7555): Tried calling: length I/flutter ( 7555): I/flutter ( 7555): When the exception was thrown, this was the stack: I/flutter ( 7555): #0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)

Can anyone help me please.

like image 994
mcfred Avatar asked Jan 24 '19 11:01

mcfred


3 Answers

Try this :

 future: getData(),
              builder: (context, AsyncSnapshot<List<User>> snapshot)
like image 174
BHUPENDRA SAHU Avatar answered Sep 22 '22 12:09

BHUPENDRA SAHU


As we found out in the comments, you are using an auth rule, which denies access for all requests:

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

I think you wanted to write something like this (read only mode):

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

Try this rule

like image 28
Kirill Shashov Avatar answered Sep 20 '22 12:09

Kirill Shashov


This is the complete solution for api integration using http

  1. Please add the http dependency: http: ^0.13.3

  2. import the http package: import 'package:http/http.dart' as http;

  3. Add Internet permission in AndroidManifest.xml.

  4. Here is the complete code of Fetch data from Api using http.

      import 'dart:convert';
      import 'package:flutter/material.dart';
    
      void main() {
        runApp(MyApp());
      }
    
     class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
                 title: 'Food recipe',
                 debugShowCheckedModeBanner: false,
                 theme: ThemeData(
                     primarySwatch: Colors.blue,
                     primaryColor: Colors.white,
                     textTheme: TextTheme(
                     bodyText2: TextStyle(color: Colors.white),
               ),
             ),
           home: DataFromApi(),
        );
       }
      }
    
      class DataFromApi extends StatefulWidget {
         @override
        _DataFromApiState createState() => _DataFromApiState();
       }         
    
      class _DataFromApiState extends State<DataFromApi> {
       Future<List<Data>> getData() async {
        var response =
         await http.get(Uri.https('jsonplaceholder.typicode.com', 'users'));
         var jsonData = jsonDecode(response.body);
        List<Data> dataList = [];
        for (var u in jsonData) {
             Data data = Data(u["name"], u["phone"], u["email"]);
             dataList.add(data);
         }
        print(dataList.length);
        return dataList;
       }
    
       @override
       Widget build(BuildContext context) {
       return Scaffold(
       appBar: AppBar(
            title: Text("Data Fetch"),
        ),
       body: Container(
           child: Card(
             child: FutureBuilder<List<Data>>(
            future: getData(),
            builder: (context, snapshot) {
                if (snapshot.data == null) {
                 return Container(
                child: Text("Loading"),
                );
             }else{
                return ListView.builder(
                      itemCount: snapshot.data!.length,
                      itemBuilder: (context, i) {
                        return ListTile(
                            title: Column(
                            children: [
                                  Text(snapshot.data![i].name),
                                  Text(snapshot.data![i].phone),
                                  Text(snapshot.data![i].email),
                            ],
                          ),
                        );
                     });
                 }
              },
           ),
          ),
        ));
     }
    }
    
    class Data {
      final String name, phone, email;
    
      Data(this.name, this.phone, this.email);
    }
    
like image 43
Nisha Jain Avatar answered Sep 19 '22 12:09

Nisha Jain