I created a Flutter app where users can add tasks to Firestore. It is all working fine including real-time updates. However, I want to extend the functionality so that a user can share tasks with other users so that both users have the ability to edit the task. How can I ensure that both users listen to the same task?
My idea was to move the tasks collection out of the user collection so that there is only 1 task collection for all users. Then I could query all tasks from all users and filter by user ID. But this would make querying very inefficient compared to now.
task.dart
class Task {
String id;
String title;
List<String> userIds; #new field to store all users with access to the task
}
firestore_service.dart
Future<void> writeTask(Task task) {
task.updateTime = DateTime.now();
return _firestore
.collection('users')
.doc(userId)
.collection('tasks')
.doc(task.id)
.set(task.toJson(), SetOptions(merge: true));
}
Stream<List<Task>> taskSnapshot() {
return _firestore
.collection('users')
.doc(userId)
.collection('tasks')
.snapshots()
.map((snapshot) {
return snapshot.docs
.map((doc) {
final data = doc.data();
Task task = Task.fromJson(data);
return task;
})
.cast<Task>()
.toList();
});
}
firestore security rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
I would need to iterate through all tasks of all users and I am concerned that this is inefficient.
No, it's not. The performance in Firestore depends on the number of documents you read and not on the total number of documents that exist in a collection. So if your query returns for example 5 documents, it doesn't matter if the collection contains one thousand documents, or one million, or even one billion documents, the time for getting those results will always be the same.
So in your case, there is nothing to worry about. Besides that, such an approach of nesting all tasks in a single collection is widely used.