L M
L M

Reputation: 71

FutureBuilder shows [instance] instead of actual data

I want to download a list from firestore and display as a list in flutter widget. The data is successfully downloaded (proved by the print(cp.data()).

However, the result shown is [Instance of '_JsonQueryDocumentSnapshot'] instead of the actual carpark data.

Could anyone pls help point out what the bug is.

Thanks


class DownloadDataScreen extends StatefulWidget {
  @override
  _DownloadDataScreen createState() => _DownloadDataScreen();
}

class _DownloadDataScreen extends State<DownloadDataScreen> {
  List<DocumentSnapshot> carparkList = []; //List for storing carparks

  void initState() {
    super.initState();
    readFromFirebase();
  }

  Future readFromFirebase() async {
    // await FirebaseFirestore.instance
    await FirebaseFirestore.instance
        .collection('carpark')
        .get()
        .then((QuerySnapshot snapshot) {
      snapshot.docs.forEach(
        (DocumentSnapshot cp) {
          carparkList.add(cp);

          print('printing cp');
          print(cp.data());
        },
      );
    });

    **return carparkList;**
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: new Text(
          'Car Park',
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
        ),
        centerTitle: true,
      ),
      body: FutureBuilder(

        future: readFromFirebase(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          List<Widget> children;
          if (snapshot.hasData) {
            children = <Widget>[
              const Icon(
                Icons.check_circle_outline,
                color: Colors.green,
                size: 60,
              ),
              Padding(
                padding: const EdgeInsets.only(top: 16),
                child: Column(
                  children: [
                    Text('Result: ${snapshot.data}'),
                  ],
                ),
              )
            ];
          } else if (snapshot.hasError) {
            children = <Widget>[
              const Icon(
                Icons.error_outline,
                color: Colors.red,
                size: 60,
              ),
              Padding(
                padding: const EdgeInsets.only(top: 16),
                child: Text('Error: ${snapshot.error}'),
              )
            ];
          } else {
            children = const <Widget>[
              SizedBox(
                child: CircularProgressIndicator(),
                width: 60,
                height: 60,
              ),
              Padding(
                padding: EdgeInsets.only(top: 16),
                child: Text('Awaiting result...'),
              )
            ];
          }
          return Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: children,
            ),
          );
        },
      ),
    );
  }

}

Upvotes: 0

Views: 320

Answers (1)

First, you don't need to call the function from the init because you already use the FutureBuilder.

Also, you don't need to cast it because when the future completes, the async snapshot already would provide you a list of DocumentSnapshot in the data and the .doc propertie.

Like this:

FutureBuilder<QuerySnapshot>(
  builder:(context,snapshot){
    if(snapshot.hasData){
      /// here your data 
      snapshot.data.docs;
    }
)

Upvotes: 1

Related Questions