I want to retrieve array from firebase or cloud_firestore.
I have no problem with retrieving single data but i am having problem with retrieving array data
please help my beginner mind is at the verge of exploding.
I have google it and gone through many tutorials videos but i can't find the solution
database image here
pubspec.yaml
dependencies:
cloud_firestore: ^0.13.6
main.dart
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(title: Text("Flutter Fire CRUD")),
body: ListPage(),
),
);
}
}
class ListPage extends StatefulWidget {
#override
_ListPageState createState() => _ListPageState();
}
class _ListPageState extends State<ListPage> {
Future _data;
Future getUsers() async {
var firestore = Firestore.instance;
firestore.collection("users").getDocuments();
QuerySnapshot qn = await firestore.collection("users").getDocuments();
return qn.documents;
}
navigateToDetail(DocumentSnapshot users) {
Navigator.push(context,
MaterialPageRoute(builder: (context) => DetailList(users: users)));
}
#override
void initState() {
super.initState();
_data = getUsers();
}
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: _data,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading ...");
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data[index].data['name']),
onTap: () {
navigateToDetail(snapshot.data[index]);
});
},
);
}
},
),
);
}
}
class DetailList extends StatefulWidget {
final DocumentSnapshot users;
DetailList({Key key, #required this.users}) : super(key: key);
#override
_DetailListState createState() => _DetailListState();
}
class _DetailListState extends State<DetailList> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("${widget.users.data['name']}"),
),
body: Column(
children: [
Container(
height: MediaQuery.of(context).size.height / 2.0,
width: MediaQuery.of(context).size.width,
child: Center(
child: Image.network(widget.users.data["img"]),
),
),
Container(
child: Card(
child: ListTile(
title: Text(widget.users.data["name"]),
subtitle: Text("Age:" + widget.users.data["age"]),
),
),
),
ListView.builder(
itemCount: widget.users.data["skills"],
itemBuilder: (context, index) {
return ListTile(
//title: Text(widget.users.data["skills"][index]),
title: here............
);
},
)
],
),
);
}
}
StreamBuilder(
stream: Firestore.instance
.collection('users')
.document(id)
.collection('chatWith')
.orderBy('timestamp', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
AppColor.colorCustom),
),
);
} else {
if (snapshot.data.documents.length == 0) {
return Container(
alignment: Alignment.center,
child: Text(
"No Chat History Found",
style: TextStyle(
color: Colors.grey,
fontWeight: FontWeight.normal,
fontSize:
Util.px_23 * SizeConfig.textMultiplier,
fontFamily: 'Roboto',
),
softWrap: true,
),
);
} else {
return ListView.builder(
padding: EdgeInsets.all(
Util.px_10 * SizeConfig.heightMultiplier),
itemBuilder: (context, index) => _listItem(
context, snapshot.data.documents[index]),
itemCount: snapshot.data.documents.length,
);
}
}
},
)
You can fetch list of data from firestore. this code I have used in my project. You can modify as per your requirement.
Related
Currently it is a listview, I know how to normally create a listview.builder but I don't know how to connect it to firebase. Im talking about the streambuilder and context and all that stuff. Really appreciate any help, Im new to flutter so sorry if this is an obvious/dumb question.
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(FireApp());
}
class FireApp extends StatefulWidget {
#override
_FireAppState createState() => _FireAppState();
}
class _FireAppState extends State<FireApp> {
final TextController = TextEditingController();
bool isChecked = false;
#override
Widget build(BuildContext context) {
CollectionReference groceries =
FirebaseFirestore.instance.collection('groceries');
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: TextField(
controller: TextController,
),
),
body: Center(
child: StreamBuilder(
stream: groceries.orderBy('name').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
return ListView(
children: snapshot.data!.docs.map((grocery) {
return Center(
child: Row(
children: [
Container(color: Colors.red,height: 50,child: Text(grocery['name'])),
Checkbox(
materialTapTargetSize: MaterialTapTargetSize.padded,
value: isChecked,
activeColor: Colors.black,
checkColor: Colors.greenAccent,
onChanged: (bool) {
setState(() {
isChecked = !isChecked;
});
}
)],
),
);
}).toList(),
);
},
),
),
floatingActionButton: FloatingActionButton(onPressed: () {
groceries.add({
'name': TextController.text,
});
},),
),
);
}
}
StreamBuilder and listview.builder sample code given below
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: groceries.orderBy('name').snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
// your list of groceries
List groceriesList =
snapshot.data.docs.map((e) => e.data()).toList();
return ListView.builder(
itemCount: groceriesList.length,
itemBuilder: (context, i) {
// build your widget here.
return Center(
child: Row(
children: [
Container(
color: Colors.red,
height: 50,
child: Text(groceriesList[i]['name']),
),
Checkbox(
materialTapTargetSize: MaterialTapTargetSize.padded,
value: isChecked,
activeColor: Colors.black,
checkColor: Colors.greenAccent,
onChanged: (bool) {
setState(() => isChecked = !isChecked);
},
)
],
),
);
},
);
},
),
I am trying to get array of images to be displayed on container widget which is stored in firebase firestore. The url is stored with index in firestore and cloud storage. Here is the complete code below. I followed the code provided online, I am not sure what I am missing or where I went wrong. pls help me out.Thanks in advance.
class NewImage extends StatefulWidget{
List<String> urls;
int currentIndex;
VoidCallback onImageTap;
NewImage({Key key,#required this.urls,#required this.currentIndex,#required this.onImageTap})
:super(key:key);
#override
_NewImage createState() => _NewImage();
}
class _NewImage extends State<NewImage>
with SingleTickerProviderStateMixin{
List<String> images = [];
final auth = FirebaseAuth.instance;
final FirebaseFirestore fb = FirebaseFirestore.instance;
#override
void initState() {
super.initState();
getImages();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SafeArea(
child: Column(
children: [
Container(
height: 160.0,
padding: EdgeInsets.symmetric(vertical: 15.0,horizontal: 15.0),
child: FutureBuilder(
future: getImages(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: snapshot.data.docs.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
contentPadding: EdgeInsets.all(8.0),
leading: Image.network(
snapshot.data.docs[index].data()["images"],
fit: BoxFit.fill),
);
});
} else if (snapshot.connectionState == ConnectionState.none) {
return Text("No data");
}
return CircularProgressIndicator();
},
),
),
],
),
),
),
);
}
Future<QuerySnapshot> getImages() async {
return FirebaseFirestore.instance.collection("users").doc(
auth.currentUser.uid).collection("images").get();
}
}
you are passing array to networkImage instead of image
change it like this
Image.network(
snapshot.data.docs[index].data()["images"][index],// [index] added
fit: BoxFit.fill),
I have this code and I am trying to make this gridview scrollable and no matter what I do it is not scrolling. I keep getting this renderoverflow error. I have tried to wrap it around SingleChildScroll view and also physics: ScrollPhysics() in its properties but nothing works. I just need to make this gridView scrollable and not the text below it. I have tried several ways but nothing as of now works for it. Might be a dumb mistake that I might be doing here but can't figure it out.
Edit: It works fine when I set singleChildScrollView after that body tag of scaffold but does not work when I apply it to GridView.
class _CartGridViewState extends State<CartGridView> {
#override
Widget build(BuildContext context) {
final User user = FirebaseAuth.instance.currentUser;
double sum = 0;
print(user);
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('Users')
.doc(user.uid)
.collection('Cart')
.snapshots(),
builder: (BuildContext context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
var document = snapshot.data.docs;
return Padding(
padding: const EdgeInsets.all(10.0),
child: SingleChildScrollView(
physics: ScrollPhysics(),
child: GridView.builder(
physics: ScrollPhysics(),
scrollDirection: Axis.vertical,
primary: false,
shrinkWrap: true,
itemCount: document.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: MediaQuery.of(context).size.height / 800,
),
itemBuilder: (context, index) {
if (document[index].data()["name"] == null) {
return Text('There are $index items in cart');
} else {
return Card(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CartView(
document[index].data()["name"],
document[index]
.data()["price"]
.toDouble(),
document[index].data()["image"],
index,
)),
);
},
child: Stack(children: [
ListView(physics: ScrollPhysics(), children: [
Hero(
tag: 'tagImage$index',
child: Image.network(
"${document[index].data()["image"]}",
height: 150,
),
),
Center(
child: Text(
"Price ${document[index].data()["price"]}")),
]),
DeleteCartItems(index),
]),
),
);
}
}),
),
);
},
);
}
}
We can make use of Expanded widget to get scrollable GridView
Please refer below code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> images = [
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
"https://images.unsplash.com/photo-1614961234425-dedd96e5e699?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxleHBsb3JlLWZlZWR8M3x8fGVufDB8fHw%3D&auto=format&fit=crop&w=500&q=60",
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: EdgeInsets.symmetric(
horizontal: 12.0,
),
child: Expanded(
child: GridView.builder(
itemCount: images.length,
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 8.0,
mainAxisSpacing: 10.0),
itemBuilder: (BuildContext context, int index) {
return Image.network(images[index]);
},
),
),
),
);
}
}
1) This is the view team/view roster screen. https://imgur.com/a/k63lQrt
class ViewTeamScreen extends StatelessWidget {
static const routeName = '/view-team';
const ViewTeamScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return StreamProvider<List<User>>.value(
value: DBService().getAllUsers,
child: Scaffold(
body: TeamList()
),
);
}
}
2) This is the team list code that displays all user data on the ViewTeamScreen and returns a TeamTile widget i created.
class TeamList extends StatefulWidget {
#override
_TeamListState createState() => _TeamListState();
}
class _TeamListState extends State<TeamList> {
#override
Widget build(BuildContext context) {
final users = Provider.of<List<User>>(context) ?? [];
//print(users);
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
return TeamTile(
user: users[index],
);
},
);
3) This is the TeamTile, which returns ListViewBuilder for a team member once they sign up to the app.
class TeamTile extends StatelessWidget {
final User user;
TeamTile({this.user});
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: 8.0),
child: Card(
margin: EdgeInsets.fromLTRB(20, 6, 20, 0),
child: ListTile(
leading: CircleAvatar(
radius: 30.0,
backgroundColor: Colors.brown,
),
title: Text(
'${user.firstName}'
" "
'${user.lastName}', //how do i make the first letter of name always CAPS?
style: TextStyle(fontSize: 23, letterSpacing: 1.0),
),
trailing: Text(user.email),
subtitle: Text('+44 0000 000 000'),
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TeamDetailScreen(),
),
);
},
),
4) This is the team detail screen, once the user taps on the ListTile in the ViewTeamScreen, this page will apear. https://imgur.com/a/7tSUO1c
class TeamDetailScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return Scaffold(
appBar: AppBar(
title: Text('Employee Contact Info'),
),
body: StreamBuilder<User>(
stream: DBService(uid: user.uid).usersData,
builder: (context, snapshot) {
if (snapshot.hasData) {
User userData = snapshot.data;
return Column(children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Name: ${userData.firstName}'
" "
'${userData.lastName}\n'
'Email: ${userData.email}',
style: TextStyle(fontSize: (20)),
),
)),
]);
} else {
return Loading();
This is going to exclude StreamProvider and just use StreamBuilder. This concept is easy to understand, as all we are doing is passing the widget.index down to other Widgets as arguments.
1
class ViewTeamScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StreamBuilder<List<User>>(
stream: DBService().getAllUsers,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<User> userData = snapshot.data;
return Scaffold(body: TeamList(myData: userData));
} else {
return Loading();
}
});
}
}
2
class TeamList extends StatefulWidget {
final List<User> myData;
TeamList({this.myData});
#override
_TeamListState createState() => _TeamListState();
}
class _TeamListState extends State<TeamList> {
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: widget.myData.length,
itemBuilder: (context, index) {
return TeamTile(
usersInfo: widget.myData[index],
);
},
);
}
}
3
class TeamTile extends StatelessWidget {
final User usersInfo;
TeamTile({this.usersInfo});
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: 8.0),
child: Card(
margin: EdgeInsets.fromLTRB(20, 6, 20, 0),
child: ListTile(
leading: CircleAvatar(
radius: 30.0,
backgroundColor: Colors.brown,
),
title: Text(
'${usersInfo.firstName}'
" "
'${usersInfo.lastName}', //how do i make the first letter of name always CAPS?
style: TextStyle(fontSize: 23, letterSpacing: 1.0),
),
trailing: Text(usersInfo.email),
subtitle: Text('+44 0000 000 000'),
onTap: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TeamDetailScreen(myDetails: usersInfo),
),
);
},
),
),
);
}
}
4
class TeamDetailScreen extends StatelessWidget {
final User myDetails;
TeamDetailScreen({this.myDetails});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Name: ${myDetails.firstName}'
" "
'${myDetails.lastName}\n'
'Email: ${myDetails.email}',
style: TextStyle(fontSize: (20)),
),
)),
]),
);
}
}
I am trying to create a detail screen to display my Firebase data from the database, and show the image along with some text data including the number of items, date, and geolocation. Is there a way to determine why the data is returning null? The navigator should navigate to the DetailPage.
Here is my Main file -
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:wasteagram/pages/create_waste.dart';
import 'package:wasteagram/services/crud.dart';
import 'pages/create_waste.dart';
import 'pages/detail_screen.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Wasteagram - ',
theme: new ThemeData(
primarySwatch: Colors.deepOrange,
),
home: new MyHomePage(title: 'Wasteagram - '),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
CrudMethods crudMethods = new CrudMethods();
Stream wasteStream;
Widget WasteList() {
return Container(
child: wasteStream != null ? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
StreamBuilder(
stream: wasteStream,
builder: (context, snapshot) {
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index){
return WidgetTile(
wastedate:
snapshot.data.documents[index].data['wastedate'],
wastenumber:
snapshot.data.documents[index].data['wastenumber']
);
});
},)
],
) : Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);
}
void initState() {
super.initState();
crudMethods.getData().then((result) {
wasteStream = result;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: WasteList(),
floatingActionButton: new FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CameraScreen())
);
},
child: new Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
class WidgetTile extends StatelessWidget {
String wastedate, wastenumber;
WidgetTile({#required this.wastedate, #required this.wastenumber});
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(wastedate),
trailing: Text(wastenumber),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailPage())
);
}
);
}
}
Here is my detail_screen.dart
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:wasteagram/data/firestore_service.dart';
class DetailPage extends StatefulWidget {
final DocumentSnapshot post;
DetailPage({this.post});
#override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.post.data["wastedate"])
),
body: Center(
child: Container(
child: Column(
children: <Widget> [
Image.network(widget.post.data["image"]),
Text(widget.post.data["wastedate"]),
Text(widget.post.data["wastenumber"]),
Text(widget.post.data["wastelocation"].toString()),
]
)
)
),
);
}
}
You are not passing DocumentSnapshot to Detail Page.
Try this:
Widget WasteList() {
return Container(
child: wasteStream != null ? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
StreamBuilder(
stream: wasteStream,
builder: (context, snapshot) {
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index){
return WidgetTile(
wastedate:
snapshot.data.documents[index].data['wastedate'],
wastenumber:
snapshot.data.documents[index].data['wastenumber'],
post:
snapshot.data.documents[index]
);
});
},)
],
) : Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);
}
class WidgetTile extends StatelessWidget {
String wastedate, wastenumber;
DocumentSnapshot post;
WidgetTile({#required this.wastedate, #required this.wastenumber,#required this.post});
#override
Widget build(BuildContext context) {
return ListTile(
title: Text(wastedate),
trailing: Text(wastenumber),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DetailPage(post: post))
);
}
);
}
}