0

希望你做得很好...

因此,我正在尝试实现一个从 Firebase(实时数据库)获取事件的日历,一切正常,但由于某种原因,这些事件从应用程序端显示为重复,而在数据库中它仅显示为一个事件

有人能告诉我为什么吗?

提前致谢

图片

class LoadDataFromFireStoreState extends State<LoadDataFromFireStore> {
  DataSnapshot querySnapshot;
  List<Color> _colorCollection;
  Query meetingQuery;
  MeetingDataSource events;
  final List<String> options = <String>['Add', 'Delete', 'Update'];
  var fireBaseInstance = FirebaseDatabase.instance.reference();
  StreamSubscription onMeetingAddedSubscription,
      onMeetingDeletedSubscription,
      onMeetingUpdatedSubscription;

  @override
  void initState() {
    _initializeEventColor();
    meetingQuery = fireBaseInstance
        .child("CalendarAppointmentCollection")
        .orderByChild('Subject');
    getDataFromDatabase().then((results) {
      setState(() {
        if (results != null) {
          querySnapshot = results;
          var collection = <Meeting>[];

          Map<dynamic, dynamic> values = querySnapshot.value;
          List<dynamic> key = values.keys.toList();
          if (values != null) {
            for (int i = 0; i < key.length; i++) {
              var data = values[key[i]];
              final Random random = new Random();
              collection.add(Meeting.map(
                  data, _colorCollection[random.nextInt(9)], key[i]));
            }
          }
          events = _getCalendarDataSource(collection);
        }
      });
    });
    super.initState();
  }

  @override
  void dispose() {
    onMeetingAddedSubscription.cancel();
    onMeetingDeletedSubscription.cancel();
    onMeetingUpdatedSubscription.cancel();
    super.dispose();
  }

  getDataFromDatabase() async {
    var getValue = await meetingQuery.once();
    wireEvents(meetingQuery);
    return getValue;
  }

  bool isInitialLoaded = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          leading: PopupMenuButton<String>(
        icon: Icon(Icons.settings),
        itemBuilder: (BuildContext context) => options.map((String choice) {
          return PopupMenuItem<String>(
            value: choice,
            child: Text(choice),
          );
        }).toList(),
        onSelected: (String value) {
          if (value == 'Add') {
            final dbRef =
                fireBaseInstance.child("CalendarAppointmentCollection");
            dbRef.push().set({
              "StartTime": '27/09/2021 09:00:00',
              "EndTime": '27/09/2021 09:00:00',
              "Subject": 'First Day of School',
            }).then((_) {
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(
                  content: Text('Successfully Added.'),
                ),
              );
            }).catchError((onError) {
              print(onError);
            });
          } else if (value == 'Delete') {
            String key =
                events.appointments[events.appointments.length - 1].key;
            fireBaseInstance
                .child("CalendarAppointmentCollection")
                .child(key)
                .remove();
          } else {
            String key = events.appointments[0].key;
            fireBaseInstance
                .child("CalendarAppointmentCollection")
                .child(key)
                .update({
              'Subject': 'First Day of School',
              'StartTime': '27/08/2021 09:00:00',
              'EndTime': '27/08/2021 10:00:00'
            });
          }
        },
      )),
      body: _showCalendar(),
    );
  }

  _showCalendar() {
    if (querySnapshot != null) {
      isInitialLoaded = true;

      if (querySnapshot.value == null) {
        return Center(
          child: CircularProgressIndicator(),
        );
      }

      return SafeArea(
        child: SfCalendar(
          view: CalendarView.month,
          initialDisplayDate: DateTime.now(),
          dataSource: events,
          monthViewSettings: MonthViewSettings(showAgenda: true),
        ),
      );
    }
  }

  void _initializeEventColor() {
    this._colorCollection = <Color>[];
    _colorCollection.add(const Color(0xFF0F8644));
    _colorCollection.add(const Color(0xFF8B1FA9));
    _colorCollection.add(const Color(0xFFD20100));
    _colorCollection.add(const Color(0xFFFC571D));
    _colorCollection.add(const Color(0xFF36B37B));
    _colorCollection.add(const Color(0xFF01A1EF));
    _colorCollection.add(const Color(0xFF3D4FB5));
    _colorCollection.add(const Color(0xFFE47C73));
    _colorCollection.add(const Color(0xFF636363));
    _colorCollection.add(const Color(0xFF0A8043));
  }

  wireEvents(Query meetingQuery) {
    onMeetingAddedSubscription =
        meetingQuery.onChildAdded.listen(onMeetingAdded);
    onMeetingDeletedSubscription =
        meetingQuery.onChildRemoved.listen(onMeetingRemoved);
    onMeetingUpdatedSubscription =
        meetingQuery.onChildChanged.listen(onMeetingChanged);
  }

  onMeetingAdded(Event event) {
    if (!isInitialLoaded) {
      return;
    }
    if (event.snapshot.value != null) {
      final Random random = new Random();
      Meeting meeting = Meeting.fromSnapShot(
          event.snapshot, _colorCollection[random.nextInt(9)]);
      events.appointments.add(meeting);
      events.notifyListeners(CalendarDataSourceAction.add, [meeting]);
    }
  }

  onMeetingRemoved(Event event) {
    if (!isInitialLoaded) {
      return;
    }
    if (event.snapshot.value != null) {
      int index = events.appointments
          .indexWhere((element) => element.key == event.snapshot.key);
      Meeting meeting = events.appointments[index];
      events.appointments.remove(meeting);
      events.notifyListeners(CalendarDataSourceAction.remove, [meeting]);
    }
  }

  onMeetingChanged(Event event) {
    if (!isInitialLoaded) {
      return;
    }
    if (event.snapshot.value != null) {
      final Random random = new Random();
      Meeting meeting = Meeting.fromSnapShot(
          event.snapshot, _colorCollection[random.nextInt(9)]);
      events.appointments.remove(meeting);
      events.notifyListeners(CalendarDataSourceAction.remove, [meeting]);
      events.appointments.add(meeting);
      events.notifyListeners(CalendarDataSourceAction.add, [meeting]);
    }
  }

  MeetingDataSource _getCalendarDataSource([List<Meeting> collection]) {
    List<Meeting> meetings = collection ?? <Meeting>[];
    return MeetingDataSource(meetings);
  }
}

class MeetingDataSource extends CalendarDataSource {
  MeetingDataSource(List<Meeting> source) {
    appointments = source;
  }

  @override
  DateTime getStartTime(int index) {
    return appointments[index].from;
  }

  @override
  DateTime getEndTime(int index) {
    return appointments[index].to;
  }

  @override
  bool isAllDay(int index) {
    return appointments[index].isAllDay;
  }

  @override
  String getSubject(int index) {
    return appointments[index].eventName;
  }

  @override
  Color getColor(int index) {
    return appointments[index].background;
  }
}

class Meeting {
  String eventName;
  DateTime from;
  DateTime to;
  Color background;
  bool isAllDay;
  String key;

  Meeting(
      {this.eventName,
      this.from,
      this.to,
      this.background,
      this.isAllDay,
      this.key});

  static Meeting fromSnapShot(DataSnapshot dataSnapshot, Color color) {
    return Meeting(
        eventName: dataSnapshot.value['Subject'],
        from: DateFormat('dd/MM/yyyy HH:mm:ss')
            .parse(dataSnapshot.value['StartTime']),
        to: DateFormat('dd/MM/yyyy HH:mm:ss')
            .parse(dataSnapshot.value['EndTime']),
        background: color,
        key: dataSnapshot.key,
        isAllDay: false);
  }

  static Meeting map(dynamic data, Color color, String key) {
    return Meeting(
        eventName: data['Subject'],
        from: DateFormat('dd/MM/yyyy HH:mm:ss').parse(data['StartTime']),
        to: DateFormat('dd/MM/yyyy HH:mm:ss').parse(data['EndTime']),
        background: color,
        key: key,
        isAllDay: false);
  }
}
4

0 回答 0