Reputation: 1272
i want to read data from firestore in a listtile i dont want to use streambuilder i want to access the documents field individually i try this but not working
class ProductList extends StatelessWidget {
Stream<DocumentSnapshot> snapshot = Firestore.instance.collection("listofprods").document('ac1').snapshots();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black)
),
child: ListTile(
title: Text(snapshot['name']),//here error
),
)
],
Upvotes: 14
Views: 72850
Reputation: 21
From the new Cloud Firestore it changed to
`FirebaseFirestore firestore = FirebaseFirestore.instance;`
this from Firestore.instance.collection("listofprods")
So if you want to To create a new Firestore instance, call the instance getter on FirebaseFirestore like above mentioned code.
Reference: https://firebase.flutter.dev/docs/firestore/usage/
Upvotes: 0
Reputation: 1
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class DataFetch extends StatefulWidget {
const DataFetch({Key key}) : super(key: key);
@override
_DataFetchState createState() => _DataFetchState();
}
class _DataFetchState extends State<DataFetch> {
List<Model> list=[];
void fetchData()async{
var data=await FirebaseFirestore.instance.collection("Items").get();
for(int i=0;i<data.docs.length;i++){
Model model=Model(data.docs[i].data()['title'], data.docs[i].data()['price'],data.docs[i].data()['imageURL'],data.docs[i].data()['desc'], data.docs[i].data()['seller']);
list.add(model);
}
}
@override
void initState() {
super.initState();
fetchData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
child: list.length==0? Center(child: Text("No Post")):ListView.builder(itemCount: list.length,
itemBuilder:(_,index){
return MyUI(list[index].title, list[index].url, list[index].price, list[index].desc, list[index].seller);
},
),
),
),
);
}
Widget MyUI(String title,String url,String price,String desc,String seller){
return Container(
child: Column(
children: [
Text(title),
Image.network(url),
Text(price),
Text(desc),
Text(seller)
],
),
);
}
}
class Model{
String title,price,url,desc,seller;
Model(this.title,this.price,this.url,this.desc,this.seller);
}
Upvotes: 0
Reputation: 4750
As Per 2021 :
streamSnapshot.data.docs
Documents Changes to doc .
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('chats/XYSDa16jZBO5CUMwIk0h/messages')
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> streamSnapshot) {
return ListView.builder(
itemCount: streamSnapshot.data.docs.length,
itemBuilder: (ctx, index) =>
Text(streamSnapshot.data.docs[index]['text']),
);
},
));
}
Upvotes: 10
Reputation: 109
This works in FlutterFire! I used DocumentSnapshot and await.
By using DocumentSnapshot
, you can get the document including document fields and its values.
A DocumentSnapshot contains data read from a document in your Cloud Firestore database. The data can be extracted with data() or get() to get a specific field.
The keyword await
will wait until any async functions are finished.
You can use the await keyword to get the completed result of an asynchronous expression. The await keyword only works within an async function.
import 'package:cloud_firestore/cloud_firestore.dart';
final db = FirebaseFirestore.instance;
// Get document with ID totalVisitors in collection dashboard
await db.collection('dashboard').doc('totalVisitors').get()
.then((DocumentSnapshot documentSnapshot) {
// Get value of field date from document dashboard/totalVisitors
firestoreDate = documentSnapshot.data()['date'];
// Get value of field weekOfYear from document dashboard/totalVisitors
firestoreWeek = documentSnapshot.data()['weekOfYear'];
}
);
Upvotes: 1
Reputation: 203
without stream and in a stateless widget, I made it with:
code:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
DocumentSnapshot snapshot; //Define snapshot
class ProductList extends StatelessWidget {
void getData()async{ //use a Async-await function to get the data
final data = await Firestore.instance.collection("listofprods").document('ac1').get(); //get the data
snapshot = data;
}
@override
Widget build(BuildContext context) {
getData(); //run the function in build
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black)
),
child: ListTile(
title: Text(snapshot.data['name'].toString()),//ok no errors.
),
)
],
),
),
),
);
}
}
the last code maybe gets some errors on diferents versions of cloud_firestore the version i use is
and other error is a red screen with some null on text, this is fix with a FutureBuilder instead to call directly de data, in this way:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class ProductList extends StatelessWidget {
@override
Widget build(BuildContext context) {
Future<String> data2() async {
var data1 = (await Firestore.instance
.collection('listofprods')
.document('ac1')
.get())
.data['name']
.toString();
return data1;
}
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
decoration:
BoxDecoration(border: Border.all(color: Colors.black)),
child: ListTile(
title: FutureBuilder(
future: data2(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
print(snapshot.data);
return Text(snapshot.data);
},
), //ok no errors.
),
),
],
),
),
),
);
}
}
Upvotes: 3
Reputation: 115
you can use StreamBuilder
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('books').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting: return new Text('Loading...');
default:
return new ListView(
children: snapshot.data.documents.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document['title']),
subtitle: new Text(document['author']),
);
}).toList(),
);
Upvotes: 1
Reputation: 2701
Use Streambuilder
for stream in flutter
StreamBuilder<DocumentSnapshot>(
stream: Firestore.instance.collection("listofprods").document('ac1').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
return _buildList(context, snapshot.data.documents);
},
);
Upvotes: 0
Reputation: 707
Try this:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class WeightChart extends StatefulWidget {
@override
_WeightChartState createState() => _WeightChartState();
}
class _WeightChartState extends State<WeightChart> {
dynamic data;
Future<dynamic> getData() async {
final DocumentReference document = Firestore.instance.collection("listofprods").document('ac1');
await document.get().then<dynamic>(( DocumentSnapshot snapshot) async{
setState(() {
data =snapshot.data;
});
});
}
@override
void initState() {
super.initState();
getData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Weight'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black)
),
child: ListTile(
title: Text(data['name']),//here error
),
)
]
)
),
);
}
}
Upvotes: 4