Is it possible to listen to changes inside referenced documents within an array 'events' in my collection 'calendar'. Within this array I save references to another collection where I store my calendar item information that I then read out per day in my calendar?
With my current code it only listens to changes in the calendar documents. But not in the referenced documents.
calendar document structure:
array : events
0: assignments/reference(docid)
1: assignments/reference(docid)
assignments document structure :
String date : dd/MM/yyyy
String eventType : Public opening
String time : HH:mm-HH:mm
String responsible : username
void listenToDocumentChanges(DateTime selectedDay) {
final formattedDate = DateFormat('yyyy-MM-dd').format(selectedDay);
FirebaseFirestore.instance
.collection('calendar')
.doc(formattedDate)
.snapshots()
.listen((calendarDocSnapshot) async {
try {
state = state.copyWith(isLoading: true, hasError: false);
if (calendarDocSnapshot.exists) {
final data = calendarDocSnapshot.data() ?? {};
final events = (data['events'] as List?)?.cast<dynamic>() ?? [];
final resolvedEvents = await resolveEvents(events);
// Update the cache with events for the selected day
state = state.copyWith(
eventsCache: {
...state.eventsCache,
formattedDate: resolvedEvents,
},
isLoading: false,
);
print(
'Updated cache with ${resolvedEvents.length} events for $formattedDate');
} else {
state = state.copyWith(
eventsCache: {
...state.eventsCache,
formattedDate: [],
},
isLoading: false,
);
print('No document exists for date: $formattedDate');
}
} catch (e) {
logError('Error in listenToDocumentChanges', e);
state = state.copyWith(
eventsCache: {
...state.eventsCache,
formattedDate: [],
},
isLoading: false,
hasError: true,
);
}
}, onError: (error) {
logError('Snapshot listener error', error);
state = state.copyWith(
eventsCache: {
...state.eventsCache,
formattedDate: [],
},
isLoading: false,
hasError: true,
);
});
}
Future<List<Map<String, dynamic>>> resolveEvents(List<dynamic> events) async {
try {
final List<Map<String, dynamic>> resolvedEvents = [];
final List<DocumentReference> references = [];
for (var event in events) {
if (event is DocumentReference) {
references.add(event);
} else if (event is Map<String, dynamic>) {
resolvedEvents.add(event);
}
}
if (references.isNotEmpty) {
final snapshots = await Future.wait(references.map((ref) => ref.get()));
for (var snapshot in snapshots) {
if (snapshot.exists) {
final data = snapshot.data() as Map<String, dynamic>?;
if (data != null) {
resolvedEvents.add({
...data,
'reference': snapshot.reference.path,
});
}
}
}
}
return resolvedEvents;
} catch (e) {
logError('Error resolving events', e);
return [];
}
}
void logError(String message, dynamic error) {
print('$message: $error');
}
If you want to also listen for changes in linked/references documents, you'll need to set up separate listeners for that. Firestore does not have a built-in feature for that.
So:
events
as you currently do.