Reputation: 423
My Flutter project has two main pages:
a) A list page which uses a QuerySnapshot
to list all the documents, and for each one of these documents you can click a button to land on
b) a detail page which lists and update the details of a single document.
Ideally the details page should use a stream too, but given this is for a single document it should be a DocumentSnapshot
stream instead.
From the QuerySnapshot
object I already can get a DocumentSnapshot
, but that seems to be static and doesn't reflect the updates in Firestore. Is there a way to get a Stream<DocumentSnapshot>
instead?
I know one way would be to reissue another query for the doc instead of a collection (similar to this FirebaseFirestore.instance.doc('order/${widget.orderid}').snapshots()
), but ideally I would like to avoid another read/query since I'm already listening to these objects. Is that possible?
final Stream<QuerySnapshot> _bundlesStream =
FirebaseFirestore.instance.collection(orderTable)
.where("pickupPending", isEqualTo: true)
.orderBy("orderDate", descending: true)
.snapshots();
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _bundlesStream,
children: snapshot.data!.docs.asMap().map((int i, DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
Order order = Order.fromJson(data);
// createWidget returns a button that goes to the detail page
// How can I get a Stream<DocumentSnapshot> here?
return MapEntry(i, createWidget(i, order));
}).values.cast<Widget>().toList(),
Upvotes: 1
Views: 999
Reputation: 1201
Ideally what you can do (assuming that your stream is at a higher level and inside some kind of state management that renders it accessible from both widgets) is to pass the id to your detail widget, then use the same stream and from the QuerySnapshot
you pick the one with that id for building your widget, this way since the DetailWiget
have a StreamBuilder
listening to the changes on the list it will rebuild if something changed on it.
The drawback of this approach is that anytime the list is updated (and not just your Document) you will get the Detail rebuilt.
Something like this:
class DetailWidget extends StatelessWidget {
const DetailWidget(this.id);
final String id;
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _bundlesStream,
builder: (context, snapshot) {
//use the ID here to retrieve the document
final document = snapshot.data.docs.firstWhere(...);
//build the widget
return Container(...);
}
);
}
}
Personally, I would use the second query even if it means another reading.
Upvotes: 1