How to make list view to listview.builder in flutter? - firebase

buildComments() {
return StreamBuilder(
stream: commentRef
.document(postId)
.collection('comments')
.orderBy('timestamp', descending: false)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return circularProgress();
}
List<Comment> comments = [];
snapshot.data.documents.forEach((doc) {
print(comments);
comments.add(Comment.fromDocument(doc));
});
return ListView(
children: comments,
);
});
}
I was trying to convert it in list view.builder but it gives me error you can can't use list instead of Widget, Can anyone solve this problem.

You should do the following:
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
contentPadding: EdgeInsets.all(8.0),
title: Text(snapshot.data.documents[index].data["name"]),
);
});
Assuming you have name in the document.

Related

How to retrieve all the Data from Firestore

enter image description here
The Picture above is my Firestore.
I'm trying to retrieve all the data from the Collection UserData.
This is the Code I used. I'm not getting any Red lines or error in Console but its not showing the data of the Collection UserData. Please Help
Container(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('UserData')
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
DocumentSnapshot book = snapshot.data.docs[index];
return ListTile(
leading: Text(book['title']),
title: Text(book['Date']),
subtitle: Text(book['Time']),
);
},
);
}
)
),

How to access data from firestore using streambuilder flutter

I want to access data from firestore but there are errors, how can i do that?
I cant use .docs in snapshot.
StreamBuilder(
stream: messageStream,
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
reverse: true,
itemCount: snapshot.data.docs.length, // error
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot ds =
snapshot.data!.docs[index]; // error
return _buildMessage(
ds["message"], myUserName == ds["sendBy"]);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
Stream:
getChatRoomMessages(chatRoomId) async {
return FirebaseFirestore.instance.collection("chatRooms").doc(chatRoomId).collection("chats").orderBy("ts", descending: true).snapshots();}
in the StreamBuilder you have to use AsyncSnapshot in with your snapshot property. That was what got it working for me
StreamBuilder<QuerySnapshot>(
stream: DatabaseMethods().getChatRoomMessages(chatRoomId),
builder: (context, AsyncSnapshot snapshot) { <<<< insert here
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
reverse: true,
itemCount: snapshot.data!.docs.length, // error
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot ds =
snapshot.data!.docs[index]; // error
return _buildMessage(
ds["message"], myUserName == ds["sendBy"]);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
I found a solution:
StreamBuilder<QuerySnapshot>(
stream: DatabaseMethods().getChatRoomMessages(chatRoomId),
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
reverse: true,
itemCount: snapshot.data!.docs.length, // error
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot ds =
snapshot.data!.docs[index]; // error
return _buildMessage(
ds["message"], myUserName == ds["sendBy"]);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),

i got this error when i am trying to use snapshot.data.docs.length in listview.buider: The getter 'docs' isn't defined for the type 'Object'

I am trying to fetch data from firebase to list all the documents in a listview builder the code is still not completed in term of displaying the database filed in the code. this is the error: The getter 'docs' isn't defined for the type 'Object'
Container(
child: StreamBuilder<Object>(
stream: _firestore
.collection('Patient')
.doc(_auth.currentUser.email)
.collection("Diabetes")
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount:
snapshot.data.docs.length, // here is the error "docs"
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot =
snapshot.data.docs[index]; // also another error "docs"
return Container();
});
}
return Center(
child: CircularProgressIndicator(),
);
}),
)
You should replace snapshot.data.docs.length with snapshot.data.length
Container(
child: StreamBuilder<Object>(
stream: _firestore
.collection('Patient')
.doc(_auth.currentUser.email)
.collection("Diabetes")
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot = snapshot.data[index];
return Container();
});
}
return Center(
child: CircularProgressIndicator(),
);
}),
)
I solved the problem by replacing StreamBuilder<Object> with StreamBuilder<QuerySnapshot>. by default the StreamBuilder comes in this form StreamBuilder<Object>

The property 'docs' cannot be unconditionally accessed because received can be 'null' Flutter

After migrate to null-safety showing this error. What should I do now?
Widget chatMessages() {
return StreamBuilder(
stream: messageStream,
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
itemCount: snapshot.data.docs.length,
reverse: true,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.docs[index];
return chatMessageTitle(
ds["message"], myUserName == ds["sendBy"]);
})
: Center(child: CircularProgressIndicator());
});
}
After adding null check (!) showing this error <the getter 'docs' is not defined for the type of object>
itemCount: snapshot.data!.docs.length,
reverse: true,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data!.docs[index];
You have to cast snapshot.data to its type. Suppose the type is QuerySnapshot (change this with the actual type of snapshot.data).
(snapshot.data! as QuerySnapshot).docs.length
Instead of typecasting at all locations, we can specify the type of stream in the StreamBuilder.
StreamBuilder<QuerySnapshot>(
...
);
Now snapshot.data is inferred as QuerySnapshot and no typecast is required.
snapshot.data!.docs.length
I have solved mine by adding StreamBuilder and builder(context, AsyncSnapshot snapshot).
Widget chatMessages() {
return StreamBuilder<QuerySnapshot>(
stream: messageStream,
builder: (context, AsyncSnapshot snapshot) {
return snapshot.hasData
? ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
itemCount: snapshot.data.docs.length,
reverse: true,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.docs[index];
return chatMessageTitle(
ds["message"], myUserName == ds["sendBy"]);
})
: Center(child: CircularProgressIndicator());
});
}
There are a few solutions:
Provide a type to your StreamBuilder:
StreamBuilder<QuerySnapshot> (...)
Provide a type to the second parameter of your builder:
builder: (context, QuerySnapshot snapshot)
Use as to downcast:
(snapshot.data! as QuerySnapshot).docs['key']
Add error and connection state checks like this:
Widget chatMessages() {
return StreamBuilder(
stream: messageStream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView.builder(
padding: EdgeInsets.only(bottom: 70, top: 16),
itemCount: snapshot.data.docs.length,
reverse: true,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.docs[index];
return chatMessageTitle(
ds["message"], myUserName == ds["sendBy"]);
});
});
}

Flutter/Dart Stream Builder Multiple Collections Firebase

I know there's probably a better way to do this but would like if its possible, to maintain the current DB structure.. (see attached)
DB Collections
Question: How can I return a StreamBuilder with a Listview(child:listTile) that displays profiles for all UID's that a particular user is following(eg: return user profiles that user "BHRaCBR.." is following). In this case im BHRaCBR...
Code below works but only returns one listTile (user):
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('following')
.doc('BHRaCBR..')
.collection('userFollowing')
.where('isApproved', isEqualTo: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot ds = snapshot.data.documents[index];
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('profile')
.where('uid', isEqualTo: ds['uid'])
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
final data0 = snapshot.data.docs;
return Container(
height: 200,
child: ListView.builder(
itemCount: data0.length,
itemBuilder: (BuildContext ctx, index) {
return Card(
child: ExpansionTile(
leading: CircleAvatar(
radius: 32,
backgroundImage: NetworkImage(
data0[index]
.data()['image_url']
.toString(),
),
),
title: Text(data0[index].data()['username']),
),
);
}),
);
});
});
});

Resources