I have cloud Firestore with one Collection , this collection has many documents and documents have many fields
I use stream to get data from the collection and it was work fine but I add some conditions that make my code complex and I didn't understand how to solve it....
if (snapshot.connectionState == ConnectionState.done) {
DocumentSnapshot doc = snapshot.data!.docs.map((e) =>
e.data()) as DocumentSnapshot<Object?>;
Map<String, dynamic> data = doc as Map<String, dynamic>;
print(data.toString());
}
I want to know how to read:
- documents in that collection
- field in this documents
this my code
Widget build(BuildContext context) {
final auth = Provider.of<AuthBase>(context,listen: false);
return StreamBuilder<QuerySnapshot>(
stream: auth.streamStateChanges()
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
}
if (snapshot.connectionState == ConnectionState.active) {
if (snapshot.connectionState == ConnectionState.done) {
print(snapshot.data?.docs.map((e) => e.data()));//???????
}
}
return Container();
});
what should I replace this code I want when ConnectionState.done to return a list of (documents , field) from my collection
*===> final _database = FirebaseFirestore.instance.collection('userInfo');
*===> Stream<QuerySnapshot> streamStateChanges() => _database.snapshots();
CodePudding user response:
read field in the specific document
The document Id of each document must be saved in its field so you can read the specific document data when you get all documents
example:
var document = db.collection("collectionName").doc();
var documentId = document.id
document.set({
"documentId":documented,
"otherField": ...,
...,
... })
for get specific field value
db.Collection("collectionName").doc("yourDocumentId").get()
.then((doc){
print("${doc.get("documentId")}");
});
your stream should be like this
db.Collection("collectionName").doc("yourDocumentId").snapshots();
fore read data like this
snapshot.data["documentId"].toString(),
///////////////////////////////////////////////////////////////////////
if your stream is return like this:
db.Collection("collectionName").snapshots();
it returns a list of documents so to reach for each document you should use it like that
switch (snapshot.connectionState) {
case ConnectionState.none:
return FutureWidgets.connectionStateNone;
case ConnectionState.waiting:
return FutureWidgets.connectionStateWaiting;
case ConnectionState.active:
return FutureWidgets.connectionStateActive;
case ConnectionState.done:
return ListView(
padding: const EdgeInsets.all(8),
children: snapshot.data!.docs.map((document) {
if(document['someFieldName'] == "someValue")
{//Todo:do what you want in this document
}
return Text("${document['fieldName'].toString()}");
}).toList(),
);
}
CodePudding user response:
abstract class AuthBase{
Stream<QuerySnapshot> streamStateChanges();
}
class Auth implements AuthBase {
final _firebaseAuth = FirebaseAuth.instance;
final _database = FirebaseFirestore.instance.collection('userInfo');
@override
Stream<QuerySnapshot> streamStateChanges() => _database.snapshots();
}
here provider
Widget build(BuildContext context) {
final auth = Provider.of<AuthBase>(context,listen: false);
return StreamBuilder<QuerySnapshot>(
stream: auth.streamStateChanges(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
case ConnectionState.done:
return ListView(
padding: const EdgeInsets.all(8),
children: snapshot.data!.docs.map((document) {
if(document['${auth.currentUser?.uid}'] == auth.currentUser?.uid)
{//Todo:do what you want in this document
}
return Text(document['username'].toString());
}).toList(),
);
}
//return UserNamePage();
return Container();
});
}
this home screen