0
votes
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class Edit extends StatefulWidget {
@override
_EditState createState() => _EditState();
}

class _EditState extends State<Edit> {


@override
Widget build(BuildContext context) {
CollectionReference users= FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser.email)
.collection('expense');

 return StreamBuilder<QuerySnapshot>(
          stream: users.snapshots(),
          builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
           // print(snapshot.data.docs.length);
            if(snapshot.hasError) {
              return CircularProgressIndicator();
            }
            return ListView(
              children: snapshot.data.docs.map((DocumentSnapshot documents) {
                return DataTable(
                  rows: [
                    DataRow(cells: [
                      DataCell(documents['amount']),
                      DataCell(documents['date']),
                      DataCell(documents['category']),
                      DataCell(documents['reference']),
                    ]),
                  ],
                );
              }).toList(),
            );
          },
        );

 }
 }

these are the exception caused by the widgets The following NoSuchMethodError was thrown building StreamBuilder(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot>#7a426): The getter 'docs' was called on null. Receiver: null Tried calling: docs

 The following _TypeError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#7a426):
 type 'int' is not a subtype of type 'Widget'
2

2 Answers

0
votes

Since it is a snapshot, it will take time for data to get loaded onto the snapshot. So, you'll have to show something else in place of your ListView() until the data is present. So you can modify your StreamBuilder's builder function to

  ...
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
   // print(snapshot.data.docs.length);
    if(snapshot.hasError) {
      return CircularProgressIndicator();
    }
    if (!snapshots.hasData) {
      return Center(
        child: Text('Data not available',),
      );
    }
  ...
0
votes

I assume you want to show the progress indicator when the app is loading the data. To do that you can check whether the app has data or not and determine what to show.

And so your builder can be updated as shown below:

builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
           // print(snapshot.data.docs.length);
            if(snapshot.data == null) {
              return CircularProgressIndicator();
            }


            return ListView(
              children: snapshot.data.docs.map((DocumentSnapshot documents) {
                return DataTable(
                  rows: [
                    DataRow(cells: [
                      DataCell(documents['amount']),
                      DataCell(documents['date']),
                      DataCell(documents['category']),
                      DataCell(documents['reference']),
                    ]),
                  ],
                );
              }).toList(),
            );
          },

The reason for the error The getter 'docs' was called on null. is because you're only checking for an error and not if the data is null. data is null until the operation completes.