challenges_utils.dart 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import 'package:cloud_firestore/cloud_firestore.dart';
  2. import 'package:geoflutterfire/geoflutterfire.dart';
  3. import 'dart:math';
  4. class ChallengesUtils {
  5. static final geo = Geoflutterfire();
  6. static final _firestore = FirebaseFirestore.instance;
  7. static Future<DocumentSnapshot<Map<String, dynamic>>> getChallenge() async {
  8. Future<DocumentSnapshot<Map<String, dynamic>>> challenge;
  9. if (await shouldGenerateChallenge()) {
  10. challenge = generateChallenge();
  11. } else {
  12. final user = _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx');
  13. challenge = user.get().then((value) => value.get('weekly_place').get());
  14. }
  15. return challenge;
  16. }
  17. static Future<bool> shouldGenerateChallenge() async {
  18. final user = _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx');
  19. DateTime now = DateTime.now();
  20. DateTime today = DateTime(now.year, now.month, now.day);
  21. DateTime lastMonday = today.subtract(Duration(days: today.weekday - 1));
  22. int secondsSinceEpoch = lastMonday.millisecondsSinceEpoch ~/ 1000;
  23. bool shouldGenerate = await user.get().then((value) {
  24. final dif = secondsSinceEpoch - value.get('last_challenge_date').seconds;
  25. return dif / 3600 / 24 > 7;
  26. });
  27. return Future.value(shouldGenerate);
  28. }
  29. static Future<DocumentSnapshot<Map<String, dynamic>>> generateChallenge() async {
  30. final user = await _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx').get();
  31. Query<Map<String, dynamic>> places = _firestore.collection('Places');
  32. double innerRadius = 3;
  33. double outerRadius = 5;
  34. String randomPlaceID = '';
  35. Stream<List<DocumentSnapshot>> possiblePlaces = geo.collection(collectionRef: places).within(
  36. center: geo.point(latitude: user.get('address').latitude, longitude: user.get('address').longitude),
  37. radius: outerRadius,
  38. field: 'location',
  39. strictMode: true);
  40. Stream<List<DocumentSnapshot>> placesTooClose = geo.collection(collectionRef: places).within(
  41. center: geo.point(latitude: user.get('address').latitude, longitude: user.get('address').longitude),
  42. radius: innerRadius,
  43. field: 'location',
  44. strictMode: true);
  45. List<DocumentSnapshot<Object?>> possiblePlacesList = await possiblePlaces.first;
  46. List<DocumentSnapshot<Object?>> placesTooCloseList = await placesTooClose.first;
  47. final ids = <String>{};
  48. for (DocumentSnapshot<Object?> element in placesTooCloseList) {
  49. ids.add(element.id);
  50. }
  51. possiblePlacesList.retainWhere((element) => !ids.contains(element.id));
  52. int numOfPlaces = possiblePlacesList.length;
  53. randomPlaceID = possiblePlacesList[Random().nextInt(numOfPlaces)].id;
  54. _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx').update({
  55. 'weekly_place': _firestore.collection('Places').doc(randomPlaceID),
  56. 'last_challenge_date': Timestamp.now(),
  57. });
  58. return _firestore.collection('Places').doc(randomPlaceID).get();
  59. }
  60. }