How to display images from Frirebase Storage in StreamBuilder - flutter

I'm trying to display images from FirebaseStorage in StreamBuilder when user add them after they have been saved in FirebaseStorage
Try #1
It works but only the last added image is shown as stream and I would like to display all the images added.
I guess this try is the better way but I can't add ListView.builder because TaskSnapshot is one data and not a list of data like ListResult that's probably why I can't diplay all images and only the last one.
Widget:
Widget loadingImage(UploadTask uploadTask) => StreamBuilder<TaskSnapshot>(
stream: uploadTask.snapshotEvents,
builder: (context, snapshot) {
if(snapshot.hasData) {
final snap = snapshot.data;
final photoName = snap!.metadata!.name;
final photoType = snap.metadata!.contentType;
final photo = snapshot.data!.ref.getDownloadURL();
return StreamBuilder(
stream: photo.asStream(),
builder: (context, AsyncSnapshot<String> snapshot) {
final image = snapshot.data;
print("Image: $image");
return Row(
children: [
Image.network(
fit: BoxFit.cover,
width: 100,
height: 100,
image!,
),
const SizedBox(width: 20,),
Text(
photoName,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 20,),
Text(
photoType!,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
)
],
);
}
);
}
return Container();
},
);
Try #2
It displays images but not as stream if one is added it's not shown if a second one is added the first one will be displayed etc
DocumentViewModel:
//----------------------------------------------------------------------------
//----------------------------- Upload instructor document list --------------
//----------------------------------------------------------------------------
static Stream<ListResult>? uploadFileList(String uid) {
try {
final result = FirebaseStorage.instance
.ref("instructorDocuments/")
.child("$uid/")
.listAll();
return result.asStream();
} on FirebaseException catch (e) {
return null;
}
}
Widget:
Widget loadingImage(UploadTask uploadTask) => StreamBuilder<ListResult>(
stream: DocumentViewModel.uploadFileList(user!.uid),
builder: (context, snapshot) {
if(snapshot.hasData) {
final snap = snapshot.data;
return ListView.builder(
itemCount: snap!.items.length,
itemBuilder: (context, index) {
final photoName = snap.items[index].name;
final photoType = snap.items[index].getMetadata();
final photo = snap.items[index].getDownloadURL();
return StreamBuilder<FullMetadata>(
stream: photoType.asStream(),
builder: (context, AsyncSnapshot<FullMetadata> snapshot) {
if(snapshot.hasData) {
final type = snapshot.data!.contentType;
return StreamBuilder(
stream: photo.asStream(),
builder: (context, AsyncSnapshot<String> snapshot) {
if(snapshot.hasData) {
final image = snapshot.data;
return Row(
children: [
Image.network(
fit: BoxFit.cover,
width: 100,
height: 100,
image!,
),
const SizedBox(width: 20,),
Text(
photoName,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 20,),
Text(
type!,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
],
);
}
return Container();
},
);
}
return Container();
}
);
},
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
);
}
if(!snapshot.hasData) {
return const Loader();
}
if(snapshot.hasError) {
return Utils.showErrorMessage(snapshot.hasError.toString());
}
else {
return Container();
}
}
);
Thanks in advance

try this without streambuilder for getting images from firebase
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class BlogView extends StatefulWidget {
const BlogView({Key? key}) : super(key: key);
#override
State<BlogView> createState() => _BlogViewState();
}
var im;
var allimgList = [];
class _BlogViewState extends State<BlogView> {
#override
void initState() {
getData();
super.initState();
setState(() {
});
}
void getData() async {
allimgList=[];
await FirebaseFirestore.instance
.collection('Names')
.snapshots()
.forEach((event) {
var n=event.docs.length;
print(event.docs.length);
for (int i = 0; i <n; i++) {
im = event.docs[i]['Images'];
var nn=event.docs[i]['Images'].length;
for(int j=0;j<nn;j++){
allimgList.add(im[j]);
setState(() {});
}
if(i==n)break;
}
print("=========>" + allimgList.toString());
});
setState(() {
});
}
#override
Widget build(BuildContext context) {
// print("================lllllllll =>" + allimgList.toString());
return Scaffold(
appBar: AppBar(
title: Text("Blog"),
),
body: Container(
child: Center(
child: allimgList.length == 0 ?
Container(
height: 500,
width: 300,
child: Center(child: Text("No Image Added Yet")),
):Container(
margin: EdgeInsets.only(top: 10),
child: GridView.builder(
padding: EdgeInsets.only(left: 10, right: 10),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 150,
childAspectRatio: 4 / 4,
crossAxisSpacing: 10,
mainAxisSpacing: 20),
itemCount: allimgList.length,
itemBuilder: (BuildContext ctx, index) {
return Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15)),
child: Image.network(
allimgList[index],
fit: BoxFit.fill,
),
);
}),
),
),
),
);
}
}

Related

Flutter : Auto refresh to update the data

I am developing a cart page which contains + and - buttons, on pressing it , the value in the backend changes, but it doesn't automatically change in the frontend.
Cartpage.dart
class CartUI extends StatefulWidget {
const CartUI({Key? key}) : super(key: key);
#override
State<CartUI> createState() => _CartUIState();
}
class _CartUIState extends State<CartUI> {
#override
Widget build(BuildContext context) {
final user = Provider.of<Userr?>(context, listen: false);
return Scaffold(
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(children: [
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('myOrders')
.doc(user?.uid)
.collection('items')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Lottie.asset('assets/animations/delivery.json'),
);
} else {
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data!.docs.length,
itemBuilder: (BuildContext context, int index) {
final DocumentSnapshot documentSnapshot =
snapshot.data!.docs[index];
return Container(
height: 120,
width: 300,
child: Row(
children: [
Column(
children: [
SizedBox(
width: 200,
child: Text(
documentSnapshot['name'],
style: const TextStyle(
color: Colors.black87,
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
Text(
documentSnapshot['quantity'].toString(),
style: const TextStyle(
fontSize: 15,
),
),
Text(
'Rs.${documentSnapshot['price'].toString()}',
style: const TextStyle(
color: Colors.black87,
fontSize: 15,
),
),
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
const SizedBox(
width: 40,
),
ElevatedButton(
onPressed: () {
if (documentSnapshot['value'] != 0.0) {
setState(() {
String id = documentSnapshot['docid'];
final user = Provider.of<Userr?>(context, listen: false);
var postDocRef = FirebaseFirestore.instance.collection('myOrders').doc(user?.uid).collection('items').doc();
Provider.of<Calculations>(context, listen: false).updatecartdata(
context,
{
'value': documentSnapshot['value'] - 0.5,
'price': documentSnapshot['price'] - (documentSnapshot['ogprice'] / 2),
},id
);
}
);
}
if (documentSnapshot['value'] ==
0.5) {
String id =
documentSnapshot['docid'];
Provider.of<ManageData>(
context,
listen: false)
.deleteData(context, id);
}
},
child: const Text('-'),
),
const SizedBox(width: 20),
Text(documentSnapshot['value']
.toString()),
const SizedBox(width: 20),
ElevatedButton(
onPressed: () {
String id =
documentSnapshot['docid'];
final user =
Provider.of<Userr?>(context,
listen: false);
var postDocRef =
FirebaseFirestore.instance
.collection('myOrders')
.doc(user?.uid)
.collection('items')
.doc();
Provider.of<Calculations>(context, listen: false).updatecartdata(
context,
{
'value': documentSnapshot['value'] + 0.5,
'price': documentSnapshot['price'] + (documentSnapshot['ogprice'] / 2),
},id
);
},
child: const Text('+'),
),
]),
],
),
],
),
);
});
}
},
),
),
_BillDetailView(),
]),
],
),
),
);
}
}
class _BillDetailView extends StatelessWidget {
#override
Widget build(BuildContext context) {
final textStyle =
Theme
.of(context)
.textTheme
.bodyText1!
.copyWith(fontSize: 16.0);
return Container(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Bill Details',
style:
Theme
.of(context)
.textTheme
.headline6!
.copyWith(fontSize: 17.0),
),
SizedBox(
height: 5,
),
FutureBuilder(
future: Provider.of<Calculations>(context, listen: false)
.getTotalCost(context),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Item total', style: textStyle),
Text('${snapshot.data}', style: textStyle),
],
);
} else if (snapshot.hasError) {
return Text("Error: ${snapshot.error.toString()}");
} else {
return const CircularProgressIndicator();
}
},
),
],
),
);
}
}
Calculation.dart
Future<dynamic> getTotalCost(BuildContext context) async {
final user = Provider.of<Userr?>(context, listen: false);
double totalCost = 0.0;
QuerySnapshot snapshot = await FirebaseFirestore.instance
.collection('myOrders')
.doc(user?.uid)
.collection('items')
.get();
for (var doc in snapshot.docs) {
totalCost += doc["price"];
}
print(totalCost.toString());
return totalCost.toString();
}
The value in the front end changes but last updated(Added or subtracted) value is not reflecting.After hot reload it changes, but not automatically.
How to change this code to automatically update the item total in the front end.
You need to use StreamBuilder instead of FutureBuilder to get live updates.
Changes your Calculation.dart to:
Stream<dynamic> getTotalCost(BuildContext context) async {
final user = Provider.of<Userr?>(context, listen: false);
double totalCost = 0.0;
QuerySnapshot snapshot = await FirebaseFirestore.instance
.collection('myOrders')
.doc(user?.uid)
.collection('items')
.snapshots();
for (var doc in snapshot.docs) {
totalCost += doc["price"];
}
print(totalCost.toString());
return totalCost.toString();
}
And change FutureBuilder to StreamBuilder:
StreamBuilder(
stream: Provider.of<Calculations>(context, listen: false)
.getTotalCost(context),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Item total', style: textStyle),
Text('${snapshot.data}', style: textStyle),
],
);
} else if (snapshot.hasError) {
return Text("Error: ${snapshot.error.toString()}");
} else {
return const CircularProgressIndicator();
}
},
),

Flutter - Nested Streambuilder and FutureBuilder

I have categories collection with category name and id fields. In foods collection, the category is a reference field. I need to display like this:click to see expected output
where title is coming from categories collection and foods are coming from foods collection.
I tried using nested streambuilder: streambuilder 1: fetch categories in a listview streambuilder 2: fetch foods in a list. Inside streambuilder 2, i have used a futurebuilder to decode the category data. If category name in food and category name from streambuilder 1 is same, the food will be displayed under that category.+
class RestaurantDetails extends StatefulWidget {
final String id;
RestaurantDetails({required this.id, super.key});
#override
State<RestaurantDetails> createState() => _RestaurantDetailsState();
}
class _RestaurantDetailsState extends State<RestaurantDetails> {
List<FoodCategory> categories = [];
List<Food> foods = [];
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: StreamBuilder(
stream: getCategories(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
categories = snapshot.data!.docs
.map((item) => FoodCategory.fromMap(item))
.toList();
return ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: categories.length,
itemBuilder: ((context, cateindex) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 10),
child: Container(
height: 30,
width: MediaQuery.of(context).size.width * 1,
color: Colors.white,
child: Text(
categories[cateindex].name.toString(),
style: Theme.of(context)
.textTheme
.headline4!
.copyWith(fontSize: 20.0),
),
),
),
StreamBuilder(
stream: FirebaseFirestore.instance
.collection('foods')
.doc(widget.id)
.collection('all')
.snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
foods = snapshot.data!.docs
.map((item) => Food.fromMap(item))
.toList();
return ListView.builder(
itemCount: foods.length,
physics:
const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: ((context, foodindex) {
var catepath = foods[foodindex].cid!.path;
String cateDocumentName = catepath
.substring(11, catepath.length);
return Column(
children: [
FutureBuilder(
future: FirebaseFirestore.instance
.collection('categories')
.doc(cateDocumentName)
.get(),
builder: ((context,
AsyncSnapshot<
DocumentSnapshot>
snapshot) {
if (snapshot.hasData) {
Map<String, dynamic> data =
snapshot.data!.data()
as Map<String,
dynamic>;
if (data['name'] ==
categories[cateindex]
.name) {
return Padding(
padding: const EdgeInsets
.symmetric(
vertical: 10,
horizontal: 10),
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius
.circular(
20),
color:
Colors.white),
height: 100,
width: MediaQuery.of(
context)
.size
.width *
1,
child: Row(
children: [
Image.network(
foods[foodindex]
.cover
.toString(),
height: 100,
width: 100,
errorBuilder:
((context,
error,
stackTrace) {
return Image
.asset(
'assets/images/food1.jpg',
height: 100,
width: 100,
);
}),
),
UIHelper
.horizontalSpaceMedium(),
Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
UIHelper
.verticalSpaceSmall(),
Text(
foods[foodindex]
.name
.toString(),
style: Theme.of(
context)
.textTheme
.bodyText1,
),
UIHelper
.verticalSpaceSmall(),
Text(
'₹${foods[foodindex].price}',
style: Theme.of(
context)
.textTheme
.bodyText1!
.copyWith(
fontSize:
14.0),
),
UIHelper
.verticalSpaceMedium(),
],
)
],
)),
);
} else {
return const SizedBox();
}
} else {
return const CircularProgressIndicator
.adaptive();
}
}))
],
);
}));
} else {
return const CircularProgressIndicator
.adaptive();
}
},
)
],
);
}));
} else {
return const CircularProgressIndicator.adaptive();
}
}),
),
);
}
getCategories() {
return FirebaseFirestore.instance
.collection('categories')
.where('uid', isEqualTo: widget.id)
.snapshots();
}
}
categories data
click to see categories
food data
click to see food data
I get the output.see my output here but when data is large (i.e large number of foods inside a category) the app hangs. Is there anyother way we can achieve this? the data should load seamlessly regardless of data size.

How to get image from API to Carousel in Flutter

I am facing this problem where I am trying to display images in a carousel. I am using the package carousel_slider: ^4.1.1. I am confused because when I hard code the content in a variable it is working perfectly displayed in my carousel widget. but the output is empty I want to use a Carousel in Flutter, so I tried to get it following the code. after running my code it's empty in output.
Map mapResponse = {};
Map dataResponse = {};
List listResponse = {} as List;
class apipro extends StatefulWidget {
const apipro({Key? key}) : super(key: key);
#override
State<apipro> createState() => _apipro();
}
class _apipro extends State<apipro> {
Future<List> team() async {
http.Response response;
response = await http.get(Uri.parse(
"https://www.archmage.lk/api/v1/webapi/getclients?page=0&limit=10"));
// ignore: unnecessary_null_comparison
Map mapResponse = json.decode(response.body);
return mapResponse['data'] as List;
}
#override
void initState() {
// team();
super.initState();
}
#override
Widget build(BuildContext context) {
return Center(
child: FutureBuilder<List?>(
future: team(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const Text(
'Loading....',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w100,
),
);
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List data = snapshot.data ?? [];
_buildItem(image, String name) {
return CarouselSlider(
options: CarouselOptions(
viewportFraction: 0.3,
autoPlayAnimationDuration:
const Duration(milliseconds: 2000),
autoPlay: true,
enlargeCenterPage: true,
height: 80),
items: <Widget>[
for (var i = 0; i < image.length; i++)
Container(
margin:
const EdgeInsets.only(top: 20.0, left: 20.0),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(image[i]),
fit: BoxFit.fitHeight,
),
// border:
// Border.all(color: Theme.of(context).accentColor),
borderRadius: BorderRadius.circular(32.0),
),
),
],
);
// ignore: dead_code
}
return ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.all(18),
itemBuilder: (context, index) {
return _buildItem(data[index]['name']?.toString() ?? '',
data[index]['image']?.toString() ?? '');
},
itemCount: data.length,
);
}
}
}),
);
}
}
I got the Proper response by Function which I created there is no error in my code. So how i can display Images in carousel_slider? Please Help. Thank you.
Try this:
Center(
child: FutureBuilder<List?>(
future: team(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const Text(
'Loading....',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w100,
),
);
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List data = snapshot.data ?? [];
return CarouselSlider.builder(
itemBuilder: (context, index, realIndex) {
return Container(
margin: const EdgeInsets.only(top: 20.0, left: 20.0),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(data[index]['image']),
fit: BoxFit.fitHeight,
),
color: Colors.red,
borderRadius: BorderRadius.circular(32.0),
),
);
},
options: CarouselOptions(
viewportFraction: 0.3,
autoPlayAnimationDuration:
const Duration(milliseconds: 2000),
autoPlay: true,
enlargeCenterPage: true,
height: 80),
itemCount: data.length,
);
}
}
}),
)
class APIPRO extends StatelessWidget {
const APIPRO({Key? key}) : super(key: key);
Future<List> team() async {
http.Response response;
response = await http.get(Uri.parse("https://www.archmage.lk/api/v1/webapi/getclients?page=0&limit=10"));
// ignore: unnecessary_null_comparison
Map mapResponse = jsonDecode(response.body);
return mapResponse['data'] as List;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FutureBuilder(
future: team(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const Text(
'Loading....',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w100,
),
);
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List data = snapshot.data ?? [];
return CarouselSlider(
options: CarouselOptions(viewportFraction: 0.3, autoPlayAnimationDuration: const Duration(milliseconds: 2000), autoPlay: true, enlargeCenterPage: true, height: 80),
items: data
.map(
(e) => Container(
margin: const EdgeInsets.only(top: 20.0, left: 20.0),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(e["image"]),
fit: BoxFit.fitHeight,
),
// border:
// Border.all(color: Theme.of(context).accentColor),
borderRadius: BorderRadius.circular(32.0),
),
),
)
.toList());
}
}
}),
),
);
}
}

Can't retrieve data from nested object firestore streambuilder listview

I'm new using firestore, so im still trying to understand it.
i had Closets on the inside i had Clothes. i want to retrieve Clothes data and show it with listview.
the problem is i failed to retrieve the data and show it into the app
this is my code for the streambuilder
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection("clothes").snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Failed to load data!");
}
if (snapshot.connectionState ==
ConnectionState.waiting) {
return ActivityServices.loadings();
}
return new ListView(
children: snapshot.data.docs
.map((DocumentSnapshot doc) {
Clothes clothes;
clothes = new Clothes(
doc.data()['clothesId'],
doc.data()['clothesName'],
doc.data()['clothesDesc'],
doc.data()['clothesImage'],
doc.data()['clothesCloset'],
doc.data()['clothesAge'],
doc.data()['clothesTag'],
doc.data()['clothesStatus'],
doc.data()['clothesLaundry'],
doc.data()['createdAt'],
doc.data()['updatedAt'],
);
print(doc.data()['clothesName']);
return CardClothesLemari(clothes: clothes);
}).toList(),
);
},
),
and this is my CardClothesLemari
final Clothes clothes;
CardClothesLemari({this.clothes, this.doc});
#override
_CardClothesLemariState createState() => _CardClothesLemariState();
}
class _CardClothesLemariState extends State<CardClothesLemari> {
#override
Widget build(BuildContext context) {
Clothes cloth = widget.clothes;
final Size size = MediaQuery.of(context).size;
if (clothes == null) {
return Container();
} else {
return Padding(
padding:
EdgeInsets.only(top: 5.0, bottom: 5.0, left: 5.0, right: 5.0),
child: InkWell(
onTap: () {
Navigator.pushNamed(context, DetailClothes.routeName,
arguments: cloth);
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 3.0,
blurRadius: 5.0)
],
color: Color(0xffA77665),
),
child: Column(children: [
Padding(
padding: EdgeInsets.only(top: size.height * 0.04),
),
Hero(
tag: 'assets/images/dummy.jpg',
child: CircleAvatar(
radius: 55,
backgroundImage: AssetImage("assets/images/dummy.jpg"),
),
),
SizedBox(height: 7.0),
Text(
//show clothes name
cloth.clothes,
style: TextStyle(
fontSize: 14,
fontFamily: GoogleFonts.openSans().fontFamily,
fontWeight: FontWeight.w700,
color: Color(0xffF0E8E1)),
textAlign: TextAlign.center,
),
Padding(
padding: EdgeInsets.only(top: 8),
child:
Container(color: Color(0xFFEBEBEB), height: 2.9657),
),
]))));
}
}
}
this is the screenshot of my firestore
Add listview inside the ConnectionState.done like below code.
if (snapshot.connectionState == ConnectionState.done) {
return new ListView(
children: snapshot.data.docs
.map((DocumentSnapshot doc) {
Clothes clothes;
clothes = new Clothes(
doc.data()['clothesId'],
doc.data()['clothesName'],
doc.data()['clothesDesc'],..........<Rest of the code>......
}
As per your database structure you're entering wrong query. Kindly take a look below code
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection('closet')
.doc('your_document_id')
.collection('clothes')
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Text('Loading...');
} else {
return ListView.builder(
itemCount: snapshot.data.docs.length,
shrinkWrap: true,
itemBuilder: (context, int index) {
QueryDocumentSnapshot<Map<String, dynamic>> data = snapshot.data.docs[index];
return Text(data.data()['clothesName']);
},
);
}
});

flutter check if data exists in firestore

I've been trying to check if user selected data matches with my firestore data.
onPressed: () async{
await Navigator.of(context).push(MaterialPageRoute(builder: (context) => Checker (
from: fromSel,
to: toSel,
)));
},
and in the second page i used
StreamBuilder(
stream: Firestore.instance
.collection('Schedules')
.where('from', isEqualTo: from)
.where('to', isEqualTo: to)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
if (!snapshot.hasData)
return Center(child: CircularProgressIndicator());
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index){
DocumentSnapshot power = snapshot.data.documents[index];
print(power['from']);
print(power['to']);
return Container(
height: 200,
width: MediaQuery.of(context).size.width,
child: Column(
children: [
Text(power['from']),
Text(power['to'])
],
),
);
}
);
}),
so the problem i'm getting is it's not displaying the value when i use .where('from', isEqualTo: from) but it works when i use .where('from', isEqualTo: 'Adama'). and also works with .where('from', isEqualTo: from) when i instantiate from value manually like String from = 'Adama'
can you please tell me what the problem is?
and below is my firestore structure
below is the whole code for the checker (renamed to search)
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:demo/BookingPages/budget.dart';
import 'package:demo/Lists/trip.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Search extends StatefulWidget {
final from, to, seat, adult, child, infant;
final DateTime arrive, depart;
Search(
{Key key, this.from, this.to, this.seat, this.arrive, this.depart, this.adult, this.infant, this.child})
: super(key: key);
#override
_SearchState createState() => _SearchState(from: from, to: to, seat: seat, adult: adult, child: child, infant: infant, arrive: arrive, depart: depart);
}
class _SearchState extends State<Search> {
// Stream<QuerySnapshot> comparision;
var from, to, seat, adult, child, infant;
final DateTime arrive, depart;
_SearchState(
{Key key, this.from, this.to, this.seat, this.arrive, this.depart, this.adult, this.infant, this.child});
Stream<QuerySnapshot> comparision(BuildContext context) async* {
try{
yield* Firestore.instance
.collection('Schedules')
.where('from', isEqualTo: from.toString())
.where('to', isEqualTo: to.toString())
// .where('dates', arrayContains: widget.depart.day)
.snapshots();
}catch(e){
print(e);
}
}
// #override
// void initState() {
// // TODO: implement initState
// comparision = Firestore.instance
// .collection('Schedules')
// .where('from', isEqualTo: from)
// .where('to', isEqualTo: to)
// .snapshots();
//
// super.initState();
// }
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: StreamBuilder(
stream: Firestore.instance
.collection('Schedules')
.where('from', isEqualTo: from)
.where('to', isEqualTo: to)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
if (!snapshot.hasData)
return Center(child: CircularProgressIndicator());
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index){
DocumentSnapshot power = snapshot.data.documents[index];
print(power['from']);
print(power['to']);
return Container(
height: 200,
width: MediaQuery.of(context).size.width,
child: Column(
children: [
Text(power['from']),
Text(power['to'])
],
),
);
}
);
}),
)
// Expanded(
// child: StreamBuilder<QuerySnapshot>(
// stream: comparision,
// builder: (BuildContext context, AsyncSnapshot<QuerySnapshot>snapshot) {
// if (!snapshot.hasData)
// return Center(child: CircularProgressIndicator());
// return ListView.builder(
// itemCount: snapshot.data.documents.length,
// itemBuilder: (context, index){
// DocumentSnapshot power = snapshot.data.documents[index];
// print(power['from']);
// print(power['to']);
// return Container(
// height: 200,
// width: MediaQuery.of(context).size.width,
// child: Column(
// children: [
// Text(power['from']),
// Text(power['to'])
// ],
// ),
// );
// }
// );
// },
// ),
// ),
],
)
);
}
}
class TripCard extends StatefulWidget {
#override
_TripCardState createState() => _TripCardState();
}
class _TripCardState extends State<TripCard> {
#override
Widget build(BuildContext context) {
return Container();
}
}
below is my first page code which includes the values
import 'package:flutter/material.dart';
import 'search.dart';
class Other extends StatefulWidget {
#override
_OtherState createState() => _OtherState();
}
class _OtherState extends State<Other> {
var from = [
'Addis Ababa', 'Adama', 'Dire Dawa', 'Ali Sabieh', 'Djibouti'
];
var fromSel = 'Addis Ababa';
var to = [
'Addis Ababa', 'Adama', 'Dire Dawa', 'Ali Sabieh', 'Djibouti'
];
var toSel = 'Djibouti';
#override
Widget build(BuildContext context) {
return Container(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: Container(
//height: 203,
child: Column(
children: [
SizedBox(height: 15,),
Container(
//decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: MediaQuery.of(context).size.width/2-19,
height: 60,
padding: EdgeInsets.symmetric(horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('From', style: TextStyle(
fontSize: 18,
color: Colors.grey
),),
SizedBox(height: 0,),
Expanded(
child: DropdownButton<String>(
underline: Container(color: Colors.transparent),
items: from.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value, style: TextStyle(
fontSize: 18
),),
);
}).toList(),
isExpanded: true,
isDense: false,
elevation: 5,
hint: Text('From'),
value: fromSel,
onChanged: (String newValue){
setState(() {
this.fromSel = newValue;
});
}),
),
],
),
),
Container(height: 50, child: VerticalDivider(color: Colors.grey)),
Container(
width: MediaQuery.of(context).size.width/2-19,
height: 60,
padding: EdgeInsets.symmetric(horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('To', style: TextStyle(
fontSize: 18,
color: Colors.grey
),),
SizedBox(height: 0,),
Expanded(
child: DropdownButton<String>(
underline: Container(color: Colors.transparent),
items: to.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value, style: TextStyle(
fontSize: 18
),),
);
}).toList(),
isExpanded: true,
isDense: false,
elevation: 5,
hint: Text('to'),
value: toSel,
onChanged: (String newValue){
setState(() {
this.toSel = newValue;
});
}),
),
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
child: MaterialButton(
onPressed: () async{
await Navigator.of(context).push(MaterialPageRoute(builder: (context) => Search (
from: fromSel,
to: toSel,
depart: _startDate,
arrive: _endDate,
seat: _options[_selectedIndex],
adult: adultSel.toString(),
child: childSel.toString(),
infant: infantSel.toString(),
)));
},
minWidth: MediaQuery
.of(context)
.size
.width - 80,
height: 45,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
color: Colors.lightGreen,
splashColor: Colors.green,
child: Text(
"Search",
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
)
],
),
),
),
);
}
}