Summary - Firestore
- Flutter course
- Advanced
- Lesson 25/69
- 4 min
Combine add, snapshots and where to make a chat screen.
Chat screen
A chat screen combines add, snapshots and where. New messages are added with add, existing messages are listened to in real time via snapshots, and messages from a specific user can be filtered with where. The stream updates automatically when data changes.
await db.collection('messages').add({
'text': msg,
'sender': 'Ali',
});
db.collection('messages').snapshots().listen((snap) {
for (final doc in snap.docs) {
print(doc.data()['text']);
}
});Practice Write a chat flow
Get db. First add a document with data {'text': 'Merhaba', 'sender': 'Ali'} to the 'messages' collection. Then filter with where('sender', isEqualTo: 'Ali') and listen to the snapshots stream. Print the text field of the first document on each snapshot. Wait 10 milliseconds.
Starter code
class QueryDocumentSnapshot {
final Map<String, dynamic> data;
QueryDocumentSnapshot(this.data);
}
class QuerySnapshot {
final List<QueryDocumentSnapshot> docs;
QuerySnapshot(this.docs);
}
class DocumentReference {
final String id;
DocumentReference(this.id);
}
class Query {
final List<QueryDocumentSnapshot> docs;
Query(this.docs);
Stream<QuerySnapshot> snapshots() async* {
yield QuerySnapshot(docs);
}
}
class CollectionReference {
final String name;
final List<Map<String, dynamic>> _store;
CollectionReference(this.name, this._store);
Future<DocumentReference> add(Map<String, dynamic> data) async {
_store.add(data);
return DocumentReference('auto-${_store.length}');
}
Query where(String field, {required String isEqualTo}) {
final filtered = _store
.where((m) => m[field] == isEqualTo)
.map((m) => QueryDocumentSnapshot(m))
.toList();
return Query(filtered);
}
}
class FirebaseFirestore {
static final FirebaseFirestore instance = FirebaseFirestore._();
FirebaseFirestore._();
final Map<String, List<Map<String, dynamic>>> _db = {};
CollectionReference collection(String name) {
_db.putIfAbsent(name, () => []);
return CollectionReference(name, _db[name]!);
}
}
void main() async {
// belge ekle
// where ile filtrele, snapshots dinle
// her snapshot'ta ilk belgenin text alanını yazdır
}Sample solution
class QueryDocumentSnapshot {
final Map<String, dynamic> data;
QueryDocumentSnapshot(this.data);
}
class QuerySnapshot {
final List<QueryDocumentSnapshot> docs;
QuerySnapshot(this.docs);
}
class DocumentReference {
final String id;
DocumentReference(this.id);
}
class Query {
final List<QueryDocumentSnapshot> docs;
Query(this.docs);
Stream<QuerySnapshot> snapshots() async* {
yield QuerySnapshot(docs);
}
}
class CollectionReference {
final String name;
final List<Map<String, dynamic>> _store;
CollectionReference(this.name, this._store);
Future<DocumentReference> add(Map<String, dynamic> data) async {
_store.add(data);
return DocumentReference('auto-${_store.length}');
}
Query where(String field, {required String isEqualTo}) {
final filtered = _store
.where((m) => m[field] == isEqualTo)
.map((m) => QueryDocumentSnapshot(m))
.toList();
return Query(filtered);
}
}
class FirebaseFirestore {
static final FirebaseFirestore instance = FirebaseFirestore._();
FirebaseFirestore._();
final Map<String, List<Map<String, dynamic>>> _db = {};
CollectionReference collection(String name) {
_db.putIfAbsent(name, () => []);
return CollectionReference(name, _db[name]!);
}
}
void main() async {
final db = FirebaseFirestore.instance;
await db.collection('messages').add({
'text': 'Merhaba',
'sender': 'Ali',
});
db.collection('messages')
.where('sender', isEqualTo: 'Ali')
.snapshots()
.listen((snap) {
print(snap.docs.first.data()['text']);
});
await Future.delayed(Duration(milliseconds: 10));
}Expected output
Merhaba
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 How is the list updated when a new message is added on the chat screen?
- The snapshots stream automatically emits a new snapshot Correct answer
- get is called manually
- The list never updates
- The app is restarted
Explanation: Since snapshots is a real-time stream, it automatically emits a new snapshot when data is added; no manual get is needed.
2 Add a message
await db.collection('messages').____({
'text': 'Merhaba',
'sender': 'Ali',
});
await db.collection('messages').add({
'text': 'Merhaba',
'sender': 'Ali',
});
Explanation: To add a new message on the chat screen you use the add method; the message data is given as a Map.
3 Chat screen parts
| Term | Meaning |
|---|---|
add |
Adds a message |
snapshots |
Listens to messages |
where |
Filters by sender |
doc.data()['text'] |
Message text |