Prechádzať zdrojové kódy

Find place for challenge with geoflutterfire

Marcin Jaborski 3 rokov pred
rodič
commit
898e664bad

+ 3 - 3
app/lib/challenges/challenge.dart

@@ -4,9 +4,9 @@ import 'package:latlong2/latlong.dart';
 
 import '../navigation/navigation_page.dart';
 
-Widget buildChallenge(
-    DocumentSnapshot<Map<String, dynamic>> data, BuildContext context) {
-  final LatLng coordinates = LatLng(data.get('location').latitude, data.get('location').longitude);
+Widget buildChallenge(DocumentSnapshot<Map<String, dynamic>> data, BuildContext context) {
+  final LatLng coordinates =
+      LatLng(data.get('location')['geopoint'].latitude, data.get('location')['geopoint'].longitude);
   return Center(
     child: Column(
       mainAxisAlignment: MainAxisAlignment.center,

+ 39 - 39
app/lib/challenges/challenges_utils.dart

@@ -1,26 +1,28 @@
 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<DocumentSnapshot<Map<String, dynamic>>> getChallenge() async {
     Future<DocumentSnapshot<Map<String, dynamic>>> challenge;
-    if(await shouldGenerateChallenge()){
+    if (await shouldGenerateChallenge()) {
       challenge = generateChallenge();
     } else {
-      final user = FirebaseFirestore.instance
-          .collection('Users')
-          .doc('tlmysIvwTBaoZKWqBofx');
+      final user = _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx');
       challenge = user.get().then((value) => value.get('weekly_place').get());
     }
     return challenge;
   }
 
   static Future<bool> shouldGenerateChallenge() async {
-    final user = FirebaseFirestore.instance
-        .collection('Users')
-        .doc('tlmysIvwTBaoZKWqBofx');
+    final user = _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx');
     DateTime now = DateTime.now();
-    int secondsSinceEpoch = now.millisecondsSinceEpoch ~/ 1000;
+    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;
@@ -28,40 +30,38 @@ class ChallengesUtils {
     return Future.value(shouldGenerate);
   }
 
-  static Future<DocumentSnapshot<Map<String, dynamic>>> generateChallenge() {
-    final user = FirebaseFirestore.instance
-        .collection('Users')
-        .doc('tlmysIvwTBaoZKWqBofx');
-    return user.get().then((value) {
-      double lat = 0.0144927536231884;
-      double lon = 0.0181818181818182;
-      double userLat = value.get('address').latitude;
-      double userLon = value.get('address').longitude;
+  static Future<DocumentSnapshot<Map<String, dynamic>>> generateChallenge() async {
+    final user = await _firestore.collection('Users').doc('tlmysIvwTBaoZKWqBofx').get();
+    Query<Map<String, dynamic>> places = _firestore.collection('Places');
+    double innerRadius = 3;
+    double outerRadius = 5;
+    String randomPlaceID = '';
 
-      double lowerLat = userLat - (lat * 15);
-      double lowerLon = userLon - (lon * 15);
-      double upperLat = userLat + (lat * 15);
-      double upperLon = userLon + (lon * 15);
+    Stream<List<DocumentSnapshot>> 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);
 
-      GeoPoint lesserGeoPoint = GeoPoint(lowerLat, lowerLon);
-      GeoPoint greaterGeoPoint = GeoPoint(upperLat, upperLon);
+    Stream<List<DocumentSnapshot>> 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);
 
-      return FirebaseFirestore.instance
-          .collection('Places')
-          .where('location', isGreaterThan: lesserGeoPoint)
-          .where('location', isLessThan: greaterGeoPoint)
-          .get()
-          .then((snapshot) {
-        int numOfPlaces = snapshot.docs.length;
-        String id = snapshot.docs[Random().nextInt(numOfPlaces)].id;
-        print('updating');
-        user.update({
-          'weekly_place':
-              FirebaseFirestore.instance.collection('Places').doc(id),
-          'last_challenge_date': Timestamp.now(),
-        });
-        return FirebaseFirestore.instance.collection('Places').doc(id).get();
-      });
+    List<DocumentSnapshot<Object?>> possiblePlacesList = await possiblePlaces.first;
+    List<DocumentSnapshot<Object?>> placesTooCloseList = await placesTooClose.first;
+    final ids = <String>{};
+    for (DocumentSnapshot<Object?> 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();
   }
 }

+ 7 - 0
app/pubspec.lock

@@ -205,6 +205,13 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  geoflutterfire:
+    dependency: "direct main"
+    description:
+      name: geoflutterfire
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.0.3"
   geolocator:
     dependency: "direct main"
     description:

+ 1 - 0
app/pubspec.yaml

@@ -49,6 +49,7 @@ dependencies:
   flutter_activity_recognition: ^1.3.0
   geolocator: ^8.2.1
   provider: ^6.0.1
+  geoflutterfire: ^3.0.3
 
 dev_dependencies:
   flutter_test: