import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:geoflutterfire/geoflutterfire.dart'; import 'dart:math'; class ChallengesUtils { static final geo = Geoflutterfire(); static final _firestore = FirebaseFirestore.instance; static Future>> getChallenge() async { Future>> challenge; if (await shouldGenerateChallenge()) { challenge = generateChallenge(); } else { final user = _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx'); challenge = user.get().then((value) => value.get('weekly_place').get()); } return challenge; } static Future shouldGenerateChallenge() async { final user = _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx'); DateTime now = DateTime.now(); DateTime today = DateTime(now.year, now.month, now.day); DateTime lastMonday = today.subtract(Duration(days: today.weekday - 1)); int secondsSinceEpoch = lastMonday.millisecondsSinceEpoch ~/ 1000; bool shouldGenerate = await user.get().then((value) { final dif = secondsSinceEpoch - value.get('last_challenge_date').seconds; return dif / 3600 / 24 > 7; }); return Future.value(shouldGenerate); } static Future>> generateChallenge() async { final user = await _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx').get(); Query> places = _firestore.collection('Places'); double innerRadius = 3; double outerRadius = 5; String randomPlaceID = ''; Stream> possiblePlaces = geo.collection(collectionRef: places).within( center: geo.point(latitude: user.get('address').latitude, longitude: user.get('address').longitude), radius: outerRadius, field: 'location', strictMode: true); Stream> placesTooClose = geo.collection(collectionRef: places).within( center: geo.point(latitude: user.get('address').latitude, longitude: user.get('address').longitude), radius: innerRadius, field: 'location', strictMode: true); List> possiblePlacesList = await possiblePlaces.first; List> placesTooCloseList = await placesTooClose.first; final ids = {}; for (DocumentSnapshot element in placesTooCloseList) { ids.add(element.id); } possiblePlacesList.retainWhere((element) => !ids.contains(element.id)); int numOfPlaces = possiblePlacesList.length; randomPlaceID = possiblePlacesList[Random().nextInt(numOfPlaces)].id; _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx').update({ 'weekly_place': _firestore.collection('Places').doc(randomPlaceID), 'last_challenge_date': Timestamp.now(), }); return _firestore.collection('Places').doc(randomPlaceID).get(); } }