Home > Enterprise >  Flutter Firestore countdown to date, seconds not matching
Flutter Firestore countdown to date, seconds not matching

Time:11-21

I have a strange issue that I don't seem to be able to figure out. In short, I store Timestamp in Firestore, retrieve them and show them in a super basic Flutter application that basically just counts down to those dates as you can see in the screenshot (ignore the fact that those dates are in the past, those things don't matter right now). The values are printed like this: Days:Hours:Minutes:Seconds. Example image

As you can see everything is kinda working as expected, except for the seconds. Both dates are counting down to 00:00:00, so the seconds should be the same and this is what I don't understand. Below is the code I'm using to build the countdown label.

class CountdownLabel extends StatefulWidget {
  final DateTime startDate;

  const CountdownLabel({
    super.key,
    required this.startDate,
  });

  @override
  CountdownLabelState createState() => CountdownLabelState();
}

class CountdownLabelState extends State<CountdownLabel> {
  Timer? timer;

  @override
  void initState() {
    super.initState();

    timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      setState(() {});
    });
  }

  Duration get durationUntilStart {
    Duration duration = widget.startDate.difference(DateTime.now());
    return duration >= duration ? duration : const Duration(seconds: 0);
  }

  Widget _durationInHoursMinSecsWidget(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        componentWidget(durationUntilStart.inDays.toString()),
        hoursMinSecSeparator,
        componentWidget(durationUntilStart.inHours.remainder(24).toString()),
        hoursMinSecSeparator,
        componentWidget(durationUntilStart.inMinutes.remainder(60).toString()),
        hoursMinSecSeparator,
        componentWidget(durationUntilStart.inSeconds.remainder(60).toString())
      ],
    );
  }

  Widget get hoursMinSecSeparator => Text(
        ':',
      );

  Widget componentWidget(String text) {
    return Row(
      children: [
        Text(
          text,
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        _durationInHoursMinSecsWidget(context),
      ],
    );
  }
}

Retrieving the Timestamps from Firestore is just through a basic service with a pagelimit of 20. Don't think this can have anything to do with it since I only have 10 records currently so all the records get loaded at the same time.

Any help in which direction to search for would be greatly appreciated.

CodePudding user response:

My best guess is that this is because you use a separate call t DateTime.now() for each countdown timer. If multiple CountdownLabelState widgets are rendered at slightly different times (as rendering each widget takes some time), they'll have slightly different now values.

If that is a problem for your use-case, consider have a single now value in the state of a parent widget - and passing that into each CountdownLabelState widget.

  • Related