Reputation: 105
Hello Guys I need help again,
I have stored two maps in one document in firestore.
Now I want to get those two maps and generate an object (CalendarEvent) out of each training.
class CalendarEvent {
final String title;
final String id;
final String date;
CalendarEvent({this.title, this.id, this.date});
Map<String, dynamic> toMap() {
Map<String, dynamic> map = {
'title': title,
'id': id,
'date': date,
};
}
factory CalendarEvent.fromJson(Map<dynamic, dynamic> json) {
return CalendarEvent(
title: 'null',
id: 'null',
date:'null'
);
}
}
For each training I want to generate an object of CalendarEvents. I tried several things, but I think im stuck.
Stream<CalendarEvent> getTrainings() {
return _firestore
.collection('users')
.doc('${_authentication.getUID()}')
.collection('user')
.doc('trainings')
.snapshots()
.map((doc) => CalendarEvent.fromJson(doc.data()));
}
}
At the moment, the factory constructor of CalendarEvent is called just one time because of one document. Is there a possible way, to call the constructor 4 times (for each training in those two maps one time)?
Thanks in advance.
Upvotes: 0
Views: 510
Reputation: 2835
I think what you are trying to achieve will be easily reached if you restructure your data.
Old data structure
users -> user_id -> user -> trainings -> data
New structure
users -> user_id -> trainings -> training_id -> data
I removed 'user' as a collection so that 'trainings' becomes a collection because this will allow you to fetch all trainings for all users or for a particular user easily.
e.g for your first training data (i.e: training1630319465118756)
users -> user_id -> trainings -> 1630319465118756 -> {name: 'Ok', date: 'August 30th, 2021'}
Then your getTrainings function becomes
Stream<CalendarEvent> getTrainings() {
return _firestore
.collection('users/${_authentication.getUID()}/trainings')
.snapshots()
.map((doc) => CalendarEvent.fromSnapshot(doc));
// I used fromSnapshot above so that we can get the id of the document.
// fromSnapshot function is shown below.
}
Change your CalendarEvent model to below
class CalendarEvent {
final String title;
final String id;
final DateTime date;
CalendarEvent({this.title, this.id, this.date});
Map<String, dynamic> toMap(CalendarEvent instance) {
Map<String, dynamic> map = {
'title': instance.title,
'id': instance.id,
'date': fromDateTime(instance.date),
};
return map;
}
factory CalendarEvent.fromJson(Map<dynamic, dynamic> json) {
return CalendarEvent(
title: json['title'] as String,
id: json['id'] as String,
date: toDateTime(json['date'] as Timestamp),
);
}
factory CalendarEvent.fromSnapshot(
DocumentSnapshot<Map<String, dynamic>> snapshot) {
Map<String, dynamic> json = snapshot.data();
json['id'] = snapshot.id;
// after adding id, we call your fromJson function
return CalendarEvent.fromJson(json);
}
}
Timestamp fromDateTime(DateTime val) =>
val == null ? null : Timestamp.fromDate(val);
DateTime toDateTime(Timestamp val) => val?.toDate();
Upvotes: 1