'Flutter Firebase fetch a nested data
So my app suggest a list of tourist places and the data is fetched from firebase. So, I have added a search bar where the user can search that tourist place and it will be shown. Now the problem is that it is not showing the searched place in the listView.
Here is the firebase ScreenShot:
Example -> I want to search and show "India Gate" in the ListView , so how should I do it. enter image description here
Here is my Code
Padding( padding: const EdgeInsets.only(top: 25, left: 0, right: 0),
child: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('States')
.snapshots(),
builder: (context, snapshot) {
var docs = snapshot.data.docs[widget.stateIndex];
if (snapshot.hasData) {
/// MediaQuery.removePadding is used to remove the blank space which appears on the top of ListView.
return MediaQuery.removePadding(
context: context,
removeTop: true,
/// Here ClipRRect is wrapped on ListView to make the Scrolling border rounded.
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(45),
topRight: Radius.circular(45)),
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
print(
"Value: ${widget.stateIndex} + ${docs['places'].length}");
print(docs.data());
print("Hello-----------------");
print(docs['places'][index]["location"]);
return Container(
height: deviceSize.height * .225,
child: Card(
elevation: 10,
margin: EdgeInsets.all(10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(20))),
child: Stack(
children: [
/// Background Place Image.
ClipRRect(
child: Image.network(
docs['places'][index]["img"],
fit: BoxFit.cover,
width: deviceSize.width,
),
borderRadius: BorderRadius.all(Radius.circular(20))),
/// Text Widget.
Positioned(
bottom: 4,
left: 10,
child: Container(
height: 25,
width: 185,
padding: EdgeInsets.only(left: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: SecondPrimaryColor,
),
child: Row(
children: [
Image.asset(
"assets/icon.png",
color: Colors.white,
height: 18,
filterQuality:
FilterQuality.high),
SizedBox(width: 10),
AutoSizeText(
docs['places'][index]["venue"],
style: TextStyle(
color: Colors.white,fontWeight: FontWeight.w600),
maxFontSize: 22,
minFontSize: 14,
),
],
),
)),
// Positioned(
// right: 30,
// bottom: 6,
// child: Container(
// height: 18,
// width: 50,
//
// decoration: BoxDecoration(
// borderRadius: BorderRadius.all(Radius.circular(10)),
// color: PrimaryColor,
// ),
// child: Icon(Icons.arrow_forward,color: SecondPrimaryColor,size: 18),
// ))
],
),
),
);
},
itemCount: docs['places'].length,
),
),
);
} else {
return Text("No Data");
}
}),
),
Solution 1:[1]
Use docs.data() to convert to Map<String, dynamic> and display your data instead of docs['places'];
Something like this:
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>( // changes made
stream: FirebaseFirestore.instance.collection('States').snapshots(),
builder: (context, snapshot) {
// changes made
if (snapshot.hasData) {
QueryDocumentSnapshot<Map<String, dynamic>> doc =
snapshot.data.docs[widget.stateIndex];
Map<String, dynamic> data = doc.data(); // changes made
/// MediaQuery.removePadding is used to remove the blank space which appears on the top of ListView.
return MediaQuery.removePadding(
context: context,
removeTop: true,
/// Here ClipRRect is wrapped on ListView to make the Scrolling border rounded.
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(45),
topRight: Radius.circular(45),
),
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
print(data);
print(
"Value: ${widget.stateIndex} + ${data['places'].length}");
print('Hello-----------------');
// changes made
print(data['places'][index]['location']);
return Container(
height: deviceSize.height * .225,
child: Card(
elevation: 10,
margin: const EdgeInsets.all(10),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Stack(
children: [
/// Background Place Image.
ClipRRect(
child: Image.network(
data['places'][index]['img'],
fit: BoxFit.cover,
width: deviceSize.width,
),
borderRadius:
const BorderRadius.all(Radius.circular(20)),
),
/// Text Widget.
Positioned(
bottom: 4,
left: 10,
child: Container(
height: 25,
width: 185,
padding: const EdgeInsets.only(left: 10),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
color: SecondPrimaryColor,
),
child: Row(
children: [
Image.asset(
'assets/icon.png',
color: Colors.white,
height: 18,
filterQuality: FilterQuality.high,
),
const SizedBox(width: 10),
AutoSizeText(
data['places'][index]['venue'],
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
),
maxFontSize: 22,
minFontSize: 14,
),
],
),
),
),
],
),
),
);
},
itemCount: data['places'].length,
),
),
);
} else {
return const Text('No Data');
}
},
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Peter O. |
