首页 > 解决方案 > 如何从firebase为tablecalendar的特定用户加载事件

问题描述

我目前正在构建一个项目,其中为用户显示培训师列表。当点击显示培训师的 listtile 时,会打开一个 modalBottomSheet,显示表格日历。虽然培训师能够将“可用时间”添加到他们的日历中,但数据必须是动态的,我将其保存在 Firestore 中。每个培训师都有自己的火力基地生成的 UID。

AvailableTime 类的结构如下:

class AvailableTime {
  String trainerID;
  DateTime date;
  DateTime startTime;
  DateTime endTime;

  AvailableTime(
      {@required this.trainerID,
      @required this.date,
      @required this.startTime,
      @required this.endTime});
}

并且按如下方式将 AvailableTime 添加到 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
    });
  }

事件映射的结构如下:

Map<DateTime, List<dynamic>>

我需要多个屏幕上的可用时间,因此我必须通过我创建的提供程序获取数据。(AvailableTime 类和 addAvailableTime() 函数也在此提供程序中。

我如何获得显示的每个培训师的可用时间,最好有一个列表,其中包含培训师的 UID 和每个 UID 保存事件地图。

提前致谢。

PS:用户在其自己的用户数据提供者中建立如下:

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();
  }
}

标签: flutterdartgoogle-cloud-firestore

解决方案


要从 firestore 获取特定的用户数据,您可以执行这样的查询

Firestore.instance
        .collection('availableTimes')
        .where('trainerID', whereIn: trainerID)
        .orderBy('startTime');

要使用表日历显示数据,请附加您的代码以匹配此

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),

展开.. _buildEventList(), )//column }

//finnaly 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(),
    );
  }

推荐阅读