Reputation: 41
Hey guys I have two top level collections, a user and a tabs collection. Within each user document I have an array field of document ids with each element in the array representing a document in the tabs collection (sort of like a reference or a pointer to that document) and I would like to listen to real time changes in the users/document with the list of ID's and to listen for changes to the corresponding documents in the tabs collection.
Below is my code so far and there are two issues with it. The stream isn’t working client side - I’m not receiving an updated snapshot when I update the document in cloud firestore. Also in order for me to get a list of tabIds I am currently making a query to cloud firestore which returns a stream however, the whereIn operator only accepts a list of objects so I’m not to sure how to handle that.
Stream<List<Tab>> get tabs {
var tabIds = _db.collection('users').doc(user.uid).snapshots().where((event) => event.get('tabs'));
return _db
.collection('tabs')
.where(FieldPath.documentId, whereIn: tabIds)
.snapshots()
.map((list) =>
list.docs.map((doc) => Tab.fromJson(doc.data())).toList());
}
Upvotes: 4
Views: 3284
Reputation: 2835
You can't directly listen to documents based on their ids, but you can add a field called docId
(the value should be the id of the document) to each document then listen to collection with this where condition.
List listOfDocIds = []; // this is the list of your docIds
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection('users')
.where('docId', whereIn: listOfDocIds),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.hasError) return Text('Something went wrong');
if (snapshot.connectionState == ConnectionState.waiting)
return CircularProgressIndicator();
List<Map<String, dynamic>> data =
snapshot.data.docs.map((e) => e.data()).toList();
print(data);
// you can build your widget here
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, i) {
return ListTile(
title: Text(data[i]['name']),
// TODO: change 'name' to name of field in users document
);
},
);
},
),
Upvotes: 3