0
votes

I was recently trying to make a Flutter application which fetches a stream of data from google cloud Firestore and displays as cards for the user on a new screen. I came across this website and followed the example closely to make a list view from stream data and was able to implement the same with not so much efforts. Here's how it looks like...

Flutter app with list view successfully implemented: enter image description here

But the problem is that when I try to convert the output to cards instead of a simple list view, I get a warning saying that my widget is overflowing. Take a look below...

Overflow warning in case of Cards: enter image description here

I tried to place the whole widget in a constrained box and also tried to make the shrinkWrap property as true but nothing seems to help. I'd be very glad if someone could help me figure out where I was wrong and point me in the right direction. Here's whole the code I wrote the for implementing the cards layout from streamBuilder class using Firestore...

(PS: the card layout and ListView layout is shown by the graph like icon on top right corner of the app[not shown in the pictures])

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';

void main() => runApp(FireList());

class FireList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firebase Listview',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyListView(),
    );
  }
}

class MyListView extends StatefulWidget {
  @override
  _MyListViewState createState() => _MyListViewState();
}

class _MyListViewState extends State<MyListView> {
  int _upCounter = 0;
  int _downCounter = 0;
  var _newdata;
  var myDatabase = Firestore.instance;

  void _putdata() {
    var myDatabase = Firestore.instance;
    myDatabase.collection('newDoc1').document("outsideData$_upCounter").setData(
      {
        "data": "Uploaded outsider data $_upCounter",
      },
    );
    _upCounter++;
  }

  @override
  Widget build(BuildContext context) {
    _putdata();
    return Scaffold(
      appBar: AppBar(
        title: Text('Firebse Listview'),
        actions: <Widget>[
          IconButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => MyList()),
              );
            },
            icon: Icon(Icons.multiline_chart),
          )
        ],
      ),
      // body: Center(
      //   child: Text(
      //       "Cloud Firestore contains this sentence:\nFetch Attemp: $_downCounter\nData: $_datafromfirestore"),
      // ),
      body: StreamBuilder(
        stream: myDatabase.collection('newDoc1').snapshots(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            Center(
              child: Text("\nCaught an error in the firebase thingie... :| "),
            );
          }
          if (!snapshot.hasData) {
            return Center(
              child: Text("\nHang On, We are building your app !"),
            );
          } else {
            var mydata = snapshot.data;
            print(mydata);
            _newdata = mydata.documents[_downCounter]["data"];
            return Center(
              child: Text(
                  "Cloud Firestore contains this sentence:\nFetch Attempt: $_downCounter\nData: $_newdata"),
            );
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _downCounter++;
          });
        },
        child: Icon(Icons.cloud_download),
        tooltip: 'Download Data',
      ),
    );
  }
}

class MyList extends StatefulWidget {
  @override
  _MyListState createState() => _MyListState();
}

class _MyListState extends State<MyList> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ListView Firestore"),
      ),
      body: StreamBuilder<QuerySnapshot>(
        stream: Firestore.instance.collection("newDoc1").snapshots(),
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
          if (snapshot.hasError) return new Text('${snapshot.error}');
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return new Center(child: new CircularProgressIndicator());
            default:
              // return ListView(
              //   padding: EdgeInsets.fromLTRB(10, 20, 10, 30),
              //   children:
              //       snapshot.data.documents.map((DocumentSnapshot document) {
              //     return new ListTile(
              //       title: new Text(document['data']),
              //     );
              //   }).toList(),
              // );
              return Card(
                child: Column(
                  children: <Widget>[
                    ListView(
                      shrinkWrap: true,
                      children: snapshot.data.documents.map(
                        (DocumentSnapshot document) {
                          return new ListTile(
                            title: new Text(document['data']),
                          );
                        },
                      ).toList(),
                    ),
                  ],
                ),
              );
          }
        },
      ),
    );
  }
}

And here's how my cloud Firestore documents look like:

enter image description here

1

1 Answers

1
votes

I think you want to show all your data in a Card right ?

I edit your code this one should work for you :

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

void main() => runApp(FireList());

class FireList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firebase Listview',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyListView(),
    );
  }
}

class MyListView extends StatefulWidget {
  @override
  _MyListViewState createState() => _MyListViewState();
}

class _MyListViewState extends State<MyListView> {
  int _upCounter = 0;
  int _downCounter = 0;
  var _newdata;
  var myDatabase = Firestore.instance;

  void _putdata() {
    var myDatabase = Firestore.instance;
    myDatabase.collection('newDoc1').document("outsideData$_upCounter").setData(
      {
        "data": "Uploaded outsider data $_upCounter",
      },
    );
    _upCounter++;
  }

  @override
  Widget build(BuildContext context) {
    _putdata();
    return Scaffold(
      appBar: AppBar(
        title: Text('Firebse Listview'),
        actions: <Widget>[
          IconButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => MyList()),
              );
            },
            icon: Icon(Icons.multiline_chart),
          )
        ],
      ),
      // body: Center(
      //   child: Text(
      //       "Cloud Firestore contains this sentence:\nFetch Attemp: $_downCounter\nData: $_datafromfirestore"),
      // ),
      body: StreamBuilder(
        stream: myDatabase.collection('newDoc1').snapshots(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            Center(
              child: Text("\nCaught an error in the firebase thingie... :| "),
            );
          }
          if (!snapshot.hasData) {
            return Center(
              child: Text("\nHang On, We are building your app !"),
            );
          } else {
            var mydata = snapshot.data;
            print(mydata);
            _newdata = mydata.documents[_downCounter]["data"];
            return Center(
              child: Text(
                  "Cloud Firestore contains this sentence:\nFetch Attempt: $_downCounter\nData: $_newdata"),
            );
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _downCounter++;
          });
        },
        child: Icon(Icons.cloud_download),
        tooltip: 'Download Data',
      ),
    );
  }
}

class MyList extends StatefulWidget {
  @override
  _MyListState createState() => _MyListState();
}

class _MyListState extends State<MyList> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ListView Firestore"),
      ),
      body: StreamBuilder<QuerySnapshot>(
        stream: Firestore.instance.collection("newDoc1").snapshots(),
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
          if (snapshot.hasError) return new Text('${snapshot.error}');
          switch (snapshot.connectionState) {
            case ConnectionState.none:
            case ConnectionState.waiting:
              return Center(
                child: CircularProgressIndicator(),
              );
            case ConnectionState.active:
            case ConnectionState.done:
              if (snapshot.hasError)
                return Center(child: Text('Error: ${snapshot.error}'));
              if (!snapshot.hasData) return Text('No data finded!');
              return Card(
                child: SingleChildScrollView(
                  child: Column(
                    children:
                      snapshot.data.documents.map((DocumentSnapshot document){
                        return new Text(document['data']);
                      }).toList()
                  ),
                ),
              );
          }
        },
      ),
    );
  }
}

you can do it this solution with ListView too, but this is much more simpler and easier I think.