'How to load events from firebase for a specific user for tablecalendar
I am currently building a project where a list of trainers is displayed for a user. When tapped on a listtile showing the trainer a modalBottomSheet opens up showing the table calendar. While the trainers are able to add 'available times' to their calendar the data has to be dynamic and I save this in firestore. Every trainer has his own firebase generated UID.
The AvailableTime class is structured as followed:
class AvailableTime {
String trainerID;
DateTime date;
DateTime startTime;
DateTime endTime;
AvailableTime(
{@required this.trainerID,
@required this.date,
@required this.startTime,
@required this.endTime});
}
And a AvailableTime is added as followed to firestore:
Future<void> addAvailableTime(
DateTime date, DateTime startTime, DateTime endTime) async {
var uid = FirebaseAuth.instance.currentUser.uid;
await FirebaseFirestore.instance.collection('availableTimes').add({
'trainerID': uid,
'date': date,
'startTime': startTime,
'endTime': endTime
});
}
A events map is structured as:
Map<DateTime, List<dynamic>>
I need the available times on multiple screens so I must get the data through the provider I created. (The AvailableTime class and addAvailableTime() function are also in this provider.
How do I get the available times for every trainer who is shown, preferred by having a List with the UID of the trainer and every UID holding an events map.
Thanks in advance.
PS: A user is build up as followed in its own user data provider:
class User with ChangeNotifier {
String uid;
String email;
String firstName;
String lastName;
bool isTrainer;
double price;
String bio;
String location;
String sportclub;
List sports;
bool isFavorite;
User(
{@required this.uid,
@required this.email,
@required this.firstName,
@required this.lastName,
@required this.isTrainer,
@required this.price,
@required this.bio,
@required this.location,
@required this.sportclub,
@required this.sports,
this.isFavorite = false});
void toggleFavoriteStatus() {
isFavorite = !isFavorite;
notifyListeners();
}
}
Solution 1:[1]
For getting specific user data from firestore you can perform such a query
Firestore.instance
.collection('availableTimes')
.where('trainerID', whereIn: trainerID)
.orderBy('startTime');
to display the data using table calendar do append your code to match this
Map<DateTime, List<AvailableTime>> events;
// convert data to match Map<DateTime, List<dynamic>>
Map<DateTime, List<AvailableTime>> _groupEvents(
List<AvailableTime> allEvents) {
Map<DateTime, List<AvailableTime>> data = {};
allEvents.forEach((event) {
var ds = format.parse(event.date);
DateTime date = DateTime(
ds.year,
ds.month,
ds.day,
);
if (data[date] == null) data[date] = [];
data[date].add(event);
});
return data;
}
// after getting the data from firebase either using streambuilder or bloc ...
//using bloc here .Data for [availableTime] is required in a list
if(state is AvailableTimeSuccess){
events = _groupEvents(state.avalaibleTimeList.availableTime);
return Column..
showCalendar(eventss: events),
Expanded.. _buildEventList(), )//column }
//finally your calendar widget
Widget showCalendar({Map<DateTime, List<AttendanceCard>> eventss}) {
return Container(
child: TableCalendar(
events: eventss,
initialCalendarFormat: CalendarFormat.week,
calendarStyle: CalendarStyle(
canEventMarkersOverflow: true,
todayColor: Colors.orange,
selectedColor: Theme.of(context).primaryColor,
todayStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.white)),
headerStyle: HeaderStyle(
centerHeaderTitle: true,
formatButtonDecoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(20.0),
),
formatButtonTextStyle: TextStyle(color: Colors.white),
formatButtonShowsNext: false,
),
startingDayOfWeek: StartingDayOfWeek.monday,
onDaySelected: (date, eventss, _) {
setState(() {
_selectedEvents = eventss;
});
},
builders: CalendarBuilders(
selectedDayBuilder: (context, date, events) => Container(
margin: const EdgeInsets.all(4.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(10.0)),
child: Text(
date.day.toString(),
style: TextStyle(color: Colors.white),
)),
todayDayBuilder: (context, date, events) => Container(
margin: const EdgeInsets.all(4.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(10.0)),
child: Text(
date.day.toString(),
style: TextStyle(color: Colors.white),
)),
),
calendarController: _calendarController,
),
);
}
//build events
Widget _buildEventList() {
return ListView(
children: _selectedEvents
.map((event) =>ListTile(title:availableTime.startTime)
.toList(),
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | marc_s |