I recommend to save the last time the user made login in the device locally, an then use it to only get the messages them didn't receive.
Here is an oversimplified example:
import 'package:cloud_firestore/cloud_firestore.dart';
/// This class represents your method to acess local data,
/// substitute this class for your method to get messages saved in the device
/// I highly recommend sembast (https://pub.dev/packages/sembast)
class LocalStorage {
static Map<String, Message> get savedMessages => {};
static DateTime get lastLogin => DateTime.now();
static void saveAllMessages(Map<String, Message> messages) {}
static void saveLastLogin(DateTime lastLogin) {}
}
class Message {
String text;
String senderId;
DateTime timestamp;
Message.fromMap(Map<String, dynamic> map) {
text = map['text'] ?? 'Error: message has no text';
senderId = map['senderId'];
timestamp = map['timestamp'];
}
Map<String, dynamic> toMap() {
return {
'text': text,
'senderId': senderId,
'timestamp': timestamp,
};
}
}
class User {
DateTime lastLogin;
String uid;
Map<String, Message> messages;
void updateMessages() {
this.messages = LocalStorage.savedMessages;
this.lastLogin = LocalStorage.lastLogin;
/// Listening to changes in the firestore collection
final firestore = Firestore.instance;
final ref = firestore.collection('users/$uid');
final query = ref.where('timestamp', isGreaterThan: this.lastLogin);
query.snapshots().listen((querySnapshot) {
/// Updating messages in the user data
querySnapshot.documents.forEach((doc) {
messages[doc.documentID] = Message.fromMap(doc.data);
});
/// Updating user last login
this.lastLogin = DateTime.now();
/// Saving changes
LocalStorage.saveAllMessages(this.messages);
LocalStorage.saveLastLogin(this.lastLogin);
});
}
}