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:
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:
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: