diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index cc2e8ddd..4e4366dd 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + + + _initContainer() async { ], ); return container; -} \ No newline at end of file +} + +Future _getUserIdFromPreferences() async { + final prefs = await SharedPreferences.getInstance(); + final encodedUser = prefs.getString("user_account"); + if (encodedUser != null) { + final user = jsonDecode(encodedUser); + return user['id']; + } + return null; +} + +void startService(String userId) async { + final service = FlutterBackgroundService(); + await service.configure( + androidConfiguration: AndroidConfiguration( + onStart: onStart, + autoStart: true, + isForegroundMode: true, + ), + iosConfiguration: IosConfiguration( + autoStart: true, + onForeground: onStart, + onBackground: onIosBackground, + ), + ); + service.startService(); +} + +Future onStart(ServiceInstance service) async { + WidgetsFlutterBinding.ensureInitialized(); + + if (service is AndroidServiceInstance) { + service.setForegroundNotificationInfo( + title: "Background Location Service", + content: "Your location is being tracked", + ); + service.setAsForegroundService(); + } + + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); + final locationService = LocationService(FirebaseFirestore.instance); + final userId = await _getUserIdFromPreferences(); + + if (userId != null) { + _startLocationUpdates(userId, locationService); + } + + service.on('stopService').listen((event) { + service.stopSelf(); + }); +} + +void _startLocationUpdates(String userId, LocationService locationService) { + Timer? timer; + Geolocator.getPositionStream( + locationSettings: const LocationSettings( + accuracy: LocationAccuracy.high, + distanceFilter: LOCATION_UPDATE_DISTANCE, + ), + ).listen((position) { + final location = LatLng(position.latitude, position.longitude); + timer?.cancel(); + timer = Timer(const Duration(milliseconds: 5000), () { + locationService.saveCurrentLocation( + userId, + location.latitude, + location.longitude, + DateTime.now().millisecondsSinceEpoch, + 0, + ); + }); + }); +} + +bool onIosBackground(ServiceInstance service) { + onStart(service); + return true; +} diff --git a/app/lib/ui/flow/home/home_screen.dart b/app/lib/ui/flow/home/home_screen.dart index 5df5f209..9f9c2b2b 100644 --- a/app/lib/ui/flow/home/home_screen.dart +++ b/app/lib/ui/flow/home/home_screen.dart @@ -47,7 +47,7 @@ class _HomeScreenState extends ConsumerState { return AppPage( body: ResumeDetector( onResume: () { - if(state.selectedSpace != null){ + if(state.selectedSpace != null) { notifier.getAllSpace(); notifier.showBatteryOptimizationDialog(); mapNotifier.checkUserPermission(); diff --git a/app/lib/ui/flow/home/map/components/selected_member_detail_view.dart b/app/lib/ui/flow/home/map/components/selected_member_detail_view.dart index 09e9656a..13483696 100644 --- a/app/lib/ui/flow/home/map/components/selected_member_detail_view.dart +++ b/app/lib/ui/flow/home/map/components/selected_member_detail_view.dart @@ -178,16 +178,18 @@ class _SelectedMemberDetailViewState extends State { } void getAddress(ApiLocation? location) async { - if (location != null) { - final latLng = LatLng(location.latitude, location.longitude); - final address = await latLng.getAddressFromLocation(); - setState(() { - this.address = address; - }); - } else { - setState(() { - address = ''; - }); + if (mounted) { + if (location != null) { + final latLng = LatLng(location.latitude, location.longitude); + final address = await latLng.getAddressFromLocation(); + setState(() { + this.address = address; + }); + } else { + setState(() { + address = ''; + }); + } } } } diff --git a/app/lib/ui/flow/home/map/map_screen.dart b/app/lib/ui/flow/home/map/map_screen.dart index 8f11bc38..5e630671 100644 --- a/app/lib/ui/flow/home/map/map_screen.dart +++ b/app/lib/ui/flow/home/map/map_screen.dart @@ -104,7 +104,7 @@ class _MapScreenState extends ConsumerState { onMemberTap: (member) { notifier.showMemberDetail(member); }, - onRelocateTap: () {}, + onRelocateTap: () => notifier.getUserLastLocation(), onPlacesTap: () { final space = widget.space; if (space != null) { diff --git a/app/lib/ui/flow/home/map/map_view_model.dart b/app/lib/ui/flow/home/map/map_view_model.dart index 07520c7c..06b1dc93 100644 --- a/app/lib/ui/flow/home/map/map_view_model.dart +++ b/app/lib/ui/flow/home/map/map_view_model.dart @@ -4,6 +4,7 @@ import 'dart:ui' as ui; import 'package:data/api/auth/auth_models.dart'; import 'package:data/api/place/api_place.dart'; import 'package:data/log/logger.dart'; +import 'package:data/service/location_manager.dart'; import 'package:data/service/permission_service.dart'; import 'package:data/service/place_service.dart'; import 'package:data/service/space_service.dart'; @@ -26,6 +27,7 @@ final mapViewStateProvider = ref.read(spaceServiceProvider), ref.read(placeServiceProvider), ref.read(permissionServiceProvider), + ref.read(locationManagerProvider), ); }); @@ -34,12 +36,14 @@ class MapViewNotifier extends StateNotifier { final SpaceService spaceService; final PlaceService placeService; final PermissionService permissionService; + final LocationManager locationManager; MapViewNotifier( this._currentUser, this.spaceService, this.placeService, this.permissionService, + this.locationManager, ) : super(const MapViewState()); void loadData(String? spaceId) { @@ -98,7 +102,11 @@ class MapViewNotifier extends StateNotifier { final List markers = []; for (final info in userInfo) { if (info.user.id == _currentUser?.id) { - _mapCameraPosition(info); + final latLng = LatLng( + info.location?.latitude ?? 0.0, + info.location?.longitude ?? 0.0, + ); + _mapCameraPosition(latLng, defaultCameraZoom); } if (info.location != null) { @@ -148,15 +156,6 @@ class MapViewNotifier extends StateNotifier { return null; } - void _mapCameraPosition(ApiUserInfo userInfo) { - final position = CameraPosition( - target: LatLng(userInfo.location?.latitude ?? 0.0, - userInfo.location?.longitude ?? 0.0), - zoom: defaultCameraZoom, - ); - state = state.copyWith(defaultPosition: position); - } - void onAddMemberTap(String spaceId) async { try { state = state.copyWith(fetchingInviteCode: true, spaceInvitationCode: ''); @@ -235,6 +234,42 @@ class MapViewNotifier extends StateNotifier { void showEnableLocationDialog() { state = state.copyWith(showLocationDialog: DateTime.now()); } + + void getUserLastLocation() async { + try { + state = state.copyWith(defaultPosition: null); + final isEnabled = await permissionService.isLocationPermissionGranted(); + if (isEnabled) { + final position = await locationManager.getLastLocation(); + final latLng = LatLng(position!.latitude, position.longitude); + _mapCameraPosition(latLng, defaultCameraZoom); + } else { + for (final info in state.userInfo) { + if (info.user.id == _currentUser?.id) { + final latLng = LatLng( + info.location?.latitude ?? 0.0, + info.location?.longitude ?? 0.0, + ); + _mapCameraPosition(latLng, defaultCameraZoom); + } + } + } + } catch (error, stack) { + logger.e( + 'MapViewNotifier: Error while getting last location', + error: error, + stackTrace: stack, + ); + } + } + + void _mapCameraPosition(LatLng latLng, double zoom) { + final cameraPosition = CameraPosition( + target: LatLng(latLng.latitude, latLng.longitude), + zoom: zoom, + ); + state = state.copyWith(defaultPosition: cameraPosition); + } } @freezed diff --git a/app/lib/ui/flow/setting/profile/profile_view_model.dart b/app/lib/ui/flow/setting/profile/profile_view_model.dart index 7b8e58e1..222ecfa3 100644 --- a/app/lib/ui/flow/setting/profile/profile_view_model.dart +++ b/app/lib/ui/flow/setting/profile/profile_view_model.dart @@ -3,21 +3,23 @@ import 'dart:io'; import 'package:data/api/auth/auth_models.dart'; import 'package:data/log/logger.dart'; import 'package:data/service/auth_service.dart'; +import 'package:data/service/location_manager.dart'; +import 'package:data/service/space_service.dart'; import 'package:data/storage/app_preferences.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:data/service/space_service.dart'; part 'profile_view_model.freezed.dart'; -final editProfileViewStateProvider = - StateNotifierProvider.autoDispose( +final editProfileViewStateProvider = StateNotifierProvider.autoDispose< + EditProfileViewNotifier, EditProfileViewState>( (ref) => EditProfileViewNotifier( ref.read(spaceServiceProvider), ref.read(authServiceProvider), ref.read(currentUserPod), + ref.read(locationManagerProvider), ), ); @@ -25,9 +27,14 @@ class EditProfileViewNotifier extends StateNotifier { final SpaceService spaceService; final AuthService authService; final ApiUser? user; - - EditProfileViewNotifier(this.spaceService, this.authService, this.user) - : super(EditProfileViewState( + final LocationManager locationManager; + + EditProfileViewNotifier( + this.spaceService, + this.authService, + this.user, + this.locationManager, + ) : super(EditProfileViewState( firstName: TextEditingController(text: user?.first_name), lastName: TextEditingController(text: user?.last_name), email: TextEditingController(text: user?.email), @@ -43,6 +50,7 @@ class EditProfileViewNotifier extends StateNotifier { spaceService.deleteUserSpaces(); authService.deleteUser(); state = state.copyWith(deletingAccount: true, accountDeleted: true); + locationManager.stopService(); } catch (error, stack) { logger.e( 'EditProfileViewState: error while delete account', @@ -69,7 +77,7 @@ class EditProfileViewNotifier extends StateNotifier { logger.e( 'EditProfileViewNotifier: error while update user profile', error: error, - stackTrace: stack + stackTrace: stack, ); state = state.copyWith(error: error); } @@ -114,7 +122,8 @@ class EditProfileViewNotifier extends StateNotifier { error: error, stackTrace: stack, ); - state = state.copyWith(profileUrl: '', uploadingImage: false, error: error); + state = + state.copyWith(profileUrl: '', uploadingImage: false, error: error); onChange(); } } diff --git a/app/pubspec.lock b/app/pubspec.lock index 1bbbf0d3..0befb375 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -202,7 +202,7 @@ packages: source: hosted version: "1.1.1" cloud_firestore: - dependency: transitive + dependency: "direct main" description: name: cloud_firestore sha256: a0f161b92610e078b4962d7e6ebeb66dc9cce0ada3514aeee442f68165d78185 @@ -517,6 +517,38 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_background_service: + dependency: "direct main" + description: + name: flutter_background_service + sha256: "30d1786c7fccba10ba1ca49297bc14343456f24e3dfd4cafc06f35de68d92619" + url: "https://pub.dev" + source: hosted + version: "5.0.6" + flutter_background_service_android: + dependency: transitive + description: + name: flutter_background_service_android + sha256: b28215e18ee743eb78105a5869a802ca7a13b01ed21a0401a4b1c4900b63676e + url: "https://pub.dev" + source: hosted + version: "6.2.3" + flutter_background_service_ios: + dependency: transitive + description: + name: flutter_background_service_ios + sha256: "9365d6b8d71ef967e32320417ea9e2444c82b526930cd6b88adb2c459e7dfc9d" + url: "https://pub.dev" + source: hosted + version: "5.0.1" + flutter_background_service_platform_interface: + dependency: transitive + description: + name: flutter_background_service_platform_interface + sha256: da16560237e055c0ef65bc93597b71d4442698acee983951474f8882c1928ea7 + url: "https://pub.dev" + source: hosted + version: "5.1.0" flutter_cache_manager: dependency: "direct main" description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index b1a4ac3f..b078da28 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -59,6 +59,7 @@ dependencies: flutter_cache_manager: ^3.3.2 permission_handler: ^11.3.1 flutter_slidable: ^3.1.0 + flutter_background_service: ^5.0.6 # map google_maps_flutter: ^2.3.1 @@ -69,6 +70,7 @@ dependencies: firebase_auth: ^4.20.0 firebase_core: ^2.23.0 firebase_storage: ^11.7.7 + cloud_firestore: ^4.15.5 google_sign_in: ^6.1.6 logger: ^2.3.0 flutter_svg: ^2.0.9 diff --git a/data/.flutter-plugins b/data/.flutter-plugins index fc05ec80..27a94871 100644 --- a/data/.flutter-plugins +++ b/data/.flutter-plugins @@ -10,6 +10,9 @@ firebase_core=/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core-2.32.0/ firebase_core_web=/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core_web-2.17.1/ firebase_storage=/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage-11.7.7/ firebase_storage_web=/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage_web-3.9.7/ +flutter_background_service=/home/kaushik/.pub-cache/hosted/pub.dev/flutter_background_service-5.0.6/ +flutter_background_service_android=/home/kaushik/.pub-cache/hosted/pub.dev/flutter_background_service_android-6.2.3/ +flutter_background_service_ios=/home/kaushik/.pub-cache/hosted/pub.dev/flutter_background_service_ios-5.0.1/ flutter_timezone=/home/kaushik/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/ geolocator=/home/kaushik/.pub-cache/hosted/pub.dev/geolocator-12.0.0/ geolocator_android=/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_android-4.6.0/ diff --git a/data/.flutter-plugins-dependencies b/data/.flutter-plugins-dependencies index 32924483..0ca9db2b 100644 --- a/data/.flutter-plugins-dependencies +++ b/data/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore-4.17.5/","native_build":true,"dependencies":["firebase_core"]},{"name":"cloud_functions","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_functions-4.7.6/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth-4.20.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core-2.32.0/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage-11.7.7/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"geolocator_apple","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.7/","native_build":true,"dependencies":[]},{"name":"google_sign_in_ios","path":"/home/kaushik/.pub-cache/hosted/pub.dev/google_sign_in_ios-5.7.6/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":true,"dependencies":[]},{"name":"permission_handler_apple","path":"/home/kaushik/.pub-cache/hosted/pub.dev/permission_handler_apple-9.4.5/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore-4.17.5/","native_build":true,"dependencies":["firebase_core"]},{"name":"cloud_functions","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_functions-4.7.6/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth-4.20.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core-2.32.0/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage-11.7.7/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"geolocator_android","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_android-4.6.0/","native_build":true,"dependencies":[]},{"name":"google_sign_in_android","path":"/home/kaushik/.pub-cache/hosted/pub.dev/google_sign_in_android-6.1.24/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":true,"dependencies":[]},{"name":"permission_handler_android","path":"/home/kaushik/.pub-cache/hosted/pub.dev/permission_handler_android-12.0.7/","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_android-2.2.3/","native_build":true,"dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore-4.17.5/","native_build":true,"dependencies":["firebase_core"]},{"name":"cloud_functions","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_functions-4.7.6/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth-4.20.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core-2.32.0/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage-11.7.7/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"geolocator_apple","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.7/","native_build":true,"dependencies":[]},{"name":"google_sign_in_ios","path":"/home/kaushik/.pub-cache/hosted/pub.dev/google_sign_in_ios-5.7.6/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":false,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/home/kaushik/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.3.2/","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"cloud_firestore","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore-4.17.5/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":false,"dependencies":[]},{"name":"firebase_auth","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth-4.20.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core-2.32.0/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage-11.7.7/","native_build":true,"dependencies":["firebase_core"]},{"name":"geolocator_windows","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_windows-0.2.3/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":false,"dependencies":[]},{"name":"path_provider_windows","path":"/home/kaushik/.pub-cache/hosted/pub.dev/path_provider_windows-2.2.1/","native_build":false,"dependencies":[]},{"name":"permission_handler_windows","path":"/home/kaushik/.pub-cache/hosted/pub.dev/permission_handler_windows-0.2.1/","native_build":true,"dependencies":[]},{"name":"shared_preferences_windows","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.3.2/","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"cloud_firestore_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore_web-3.12.5/","dependencies":["firebase_core_web"]},{"name":"cloud_functions_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_functions_web-4.9.6/","dependencies":["firebase_core_web"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","dependencies":[]},{"name":"firebase_auth_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth_web-5.12.0/","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core_web-2.17.1/","dependencies":[]},{"name":"firebase_storage_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage_web-3.9.7/","dependencies":["firebase_core_web"]},{"name":"flutter_timezone","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","dependencies":[]},{"name":"geolocator_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_web-4.0.0/","dependencies":[]},{"name":"google_sign_in_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/google_sign_in_web-0.12.4/","dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","dependencies":[]},{"name":"permission_handler_html","path":"/home/kaushik/.pub-cache/hosted/pub.dev/permission_handler_html-0.1.1/","dependencies":[]},{"name":"shared_preferences_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_web-2.3.0/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["cloud_firestore_web","firebase_core"]},{"name":"cloud_firestore_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"cloud_functions","dependencies":["cloud_functions_web","firebase_core"]},{"name":"cloud_functions_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"device_info_plus","dependencies":[]},{"name":"firebase_auth","dependencies":["firebase_auth_web","firebase_core"]},{"name":"firebase_auth_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core","firebase_storage_web"]},{"name":"firebase_storage_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"flutter_timezone","dependencies":[]},{"name":"geolocator","dependencies":["geolocator_android","geolocator_apple","geolocator_web","geolocator_windows"]},{"name":"geolocator_android","dependencies":[]},{"name":"geolocator_apple","dependencies":[]},{"name":"geolocator_web","dependencies":[]},{"name":"geolocator_windows","dependencies":[]},{"name":"google_sign_in","dependencies":["google_sign_in_android","google_sign_in_ios","google_sign_in_web"]},{"name":"google_sign_in_android","dependencies":[]},{"name":"google_sign_in_ios","dependencies":[]},{"name":"google_sign_in_web","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":["permission_handler_android","permission_handler_apple","permission_handler_html","permission_handler_windows"]},{"name":"permission_handler_android","dependencies":[]},{"name":"permission_handler_apple","dependencies":[]},{"name":"permission_handler_html","dependencies":[]},{"name":"permission_handler_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2024-07-03 14:46:27.136362","version":"3.22.2"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore-4.17.5/","native_build":true,"dependencies":["firebase_core"]},{"name":"cloud_functions","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_functions-4.7.6/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth-4.20.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core-2.32.0/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage-11.7.7/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_background_service_ios","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_background_service_ios-5.0.1/","native_build":true,"dependencies":[]},{"name":"flutter_timezone","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"geolocator_apple","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.7/","native_build":true,"dependencies":[]},{"name":"google_sign_in_ios","path":"/home/kaushik/.pub-cache/hosted/pub.dev/google_sign_in_ios-5.7.6/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":true,"dependencies":[]},{"name":"permission_handler_apple","path":"/home/kaushik/.pub-cache/hosted/pub.dev/permission_handler_apple-9.4.5/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore-4.17.5/","native_build":true,"dependencies":["firebase_core"]},{"name":"cloud_functions","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_functions-4.7.6/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth-4.20.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core-2.32.0/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage-11.7.7/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_background_service_android","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_background_service_android-6.2.3/","native_build":true,"dependencies":[]},{"name":"flutter_timezone","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"geolocator_android","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_android-4.6.0/","native_build":true,"dependencies":[]},{"name":"google_sign_in_android","path":"/home/kaushik/.pub-cache/hosted/pub.dev/google_sign_in_android-6.1.24/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":true,"dependencies":[]},{"name":"permission_handler_android","path":"/home/kaushik/.pub-cache/hosted/pub.dev/permission_handler_android-12.0.7/","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_android-2.2.3/","native_build":true,"dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore-4.17.5/","native_build":true,"dependencies":["firebase_core"]},{"name":"cloud_functions","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_functions-4.7.6/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":true,"dependencies":[]},{"name":"firebase_auth","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth-4.20.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core-2.32.0/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage-11.7.7/","native_build":true,"dependencies":["firebase_core"]},{"name":"flutter_timezone","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","native_build":true,"dependencies":[]},{"name":"geolocator_apple","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.7/","native_build":true,"dependencies":[]},{"name":"google_sign_in_ios","path":"/home/kaushik/.pub-cache/hosted/pub.dev/google_sign_in_ios-5.7.6/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.4.0/","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":false,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/home/kaushik/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.3.2/","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"cloud_firestore","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore-4.17.5/","native_build":true,"dependencies":["firebase_core"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","native_build":false,"dependencies":[]},{"name":"firebase_auth","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth-4.20.0/","native_build":true,"dependencies":["firebase_core"]},{"name":"firebase_core","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core-2.32.0/","native_build":true,"dependencies":[]},{"name":"firebase_storage","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage-11.7.7/","native_build":true,"dependencies":["firebase_core"]},{"name":"geolocator_windows","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_windows-0.2.3/","native_build":true,"dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","native_build":false,"dependencies":[]},{"name":"path_provider_windows","path":"/home/kaushik/.pub-cache/hosted/pub.dev/path_provider_windows-2.2.1/","native_build":false,"dependencies":[]},{"name":"permission_handler_windows","path":"/home/kaushik/.pub-cache/hosted/pub.dev/permission_handler_windows-0.2.1/","native_build":true,"dependencies":[]},{"name":"shared_preferences_windows","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.3.2/","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"cloud_firestore_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_firestore_web-3.12.5/","dependencies":["firebase_core_web"]},{"name":"cloud_functions_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/cloud_functions_web-4.9.6/","dependencies":["firebase_core_web"]},{"name":"device_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/device_info_plus-9.1.2/","dependencies":[]},{"name":"firebase_auth_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_auth_web-5.12.0/","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_core_web-2.17.1/","dependencies":[]},{"name":"firebase_storage_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/firebase_storage_web-3.9.7/","dependencies":["firebase_core_web"]},{"name":"flutter_timezone","path":"/home/kaushik/.pub-cache/hosted/pub.dev/flutter_timezone-1.0.8/","dependencies":[]},{"name":"geolocator_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/geolocator_web-4.0.0/","dependencies":[]},{"name":"google_sign_in_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/google_sign_in_web-0.12.4/","dependencies":[]},{"name":"package_info_plus","path":"/home/kaushik/.pub-cache/hosted/pub.dev/package_info_plus-8.0.0/","dependencies":[]},{"name":"permission_handler_html","path":"/home/kaushik/.pub-cache/hosted/pub.dev/permission_handler_html-0.1.1/","dependencies":[]},{"name":"shared_preferences_web","path":"/home/kaushik/.pub-cache/hosted/pub.dev/shared_preferences_web-2.3.0/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["cloud_firestore_web","firebase_core"]},{"name":"cloud_firestore_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"cloud_functions","dependencies":["cloud_functions_web","firebase_core"]},{"name":"cloud_functions_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"device_info_plus","dependencies":[]},{"name":"firebase_auth","dependencies":["firebase_auth_web","firebase_core"]},{"name":"firebase_auth_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core","firebase_storage_web"]},{"name":"firebase_storage_web","dependencies":["firebase_core","firebase_core_web"]},{"name":"flutter_background_service","dependencies":["flutter_background_service_android","flutter_background_service_ios"]},{"name":"flutter_background_service_android","dependencies":[]},{"name":"flutter_background_service_ios","dependencies":[]},{"name":"flutter_timezone","dependencies":[]},{"name":"geolocator","dependencies":["geolocator_android","geolocator_apple","geolocator_web","geolocator_windows"]},{"name":"geolocator_android","dependencies":[]},{"name":"geolocator_apple","dependencies":[]},{"name":"geolocator_web","dependencies":[]},{"name":"geolocator_windows","dependencies":[]},{"name":"google_sign_in","dependencies":["google_sign_in_android","google_sign_in_ios","google_sign_in_web"]},{"name":"google_sign_in_android","dependencies":[]},{"name":"google_sign_in_ios","dependencies":[]},{"name":"google_sign_in_web","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":["permission_handler_android","permission_handler_apple","permission_handler_html","permission_handler_windows"]},{"name":"permission_handler_android","dependencies":[]},{"name":"permission_handler_apple","dependencies":[]},{"name":"permission_handler_html","dependencies":[]},{"name":"permission_handler_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]}],"date_created":"2024-07-10 16:30:02.971381","version":"3.22.2"} \ No newline at end of file diff --git a/data/lib/api/auth/api_user_service.dart b/data/lib/api/auth/api_user_service.dart index 93e8a6cd..ec0c4307 100644 --- a/data/lib/api/auth/api_user_service.dart +++ b/data/lib/api/auth/api_user_service.dart @@ -4,6 +4,7 @@ import 'package:data/service/device_service.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../service/location_manager.dart'; import '../../storage/app_preferences.dart'; import 'auth_models.dart'; @@ -14,6 +15,7 @@ final apiUserServiceProvider = StateProvider((ref) => ApiUserService( ref.read(currentUserSessionJsonPod.notifier), ref.read(currentUserSessionJsonPod.notifier), ref.read(isOnboardingShownPod.notifier), + ref.read(locationManagerProvider), )); class ApiUserService { @@ -23,14 +25,17 @@ class ApiUserService { final StateController currentUserSpaceId; final StateController userSessionJsonNotifier; final StateController onBoardNotifier; + final LocationManager locationManager; ApiUserService( - this._db, - this._device, - this.userJsonNotifier, - this.currentUserSpaceId, - this.userSessionJsonNotifier, - this.onBoardNotifier); + this._db, + this._device, + this.userJsonNotifier, + this.currentUserSpaceId, + this.userSessionJsonNotifier, + this.onBoardNotifier, + this.locationManager, + ); CollectionReference get _userRef => _db.collection("users").withConverter( @@ -186,12 +191,11 @@ class ApiUserService { } Future signOut() async { - // locationManager.stopLocationTracking(); + locationManager.stopService(); userJsonNotifier.state = null; userSessionJsonNotifier.state = null; onBoardNotifier.state = false; currentUserSpaceId.state = null; FirebaseAuth.instance.signOut(); - // locationManager.stopService(); } } diff --git a/data/lib/service/location_manager.dart b/data/lib/service/location_manager.dart new file mode 100644 index 00000000..e35d51c0 --- /dev/null +++ b/data/lib/service/location_manager.dart @@ -0,0 +1,42 @@ +// ignore_for_file: constant_identifier_names, non_constant_identifier_names + +import 'dart:async'; +import 'package:flutter_background_service/flutter_background_service.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:permission_handler/permission_handler.dart'; + +import 'location_service.dart'; + +const LOCATION_UPDATE_INTERVAL = 10000; // milliseconds +const LOCATION_UPDATE_DISTANCE = 10; // meters + +final locationManagerProvider = + Provider((ref) => LocationManager(ref.read(locationServiceProvider))); + +class LocationManager { + final LocationService locationService; + + LocationManager(this.locationService); + + Future isServiceRunning() async { + final service = FlutterBackgroundService(); + return await service.isRunning(); + } + + Future getLastLocation() async { + if (!await Geolocator.isLocationServiceEnabled()) return null; + + if (await Permission.location.isDenied) { + await Permission.location.request(); + if (await Permission.location.isDenied) { + return null; + } + } + return await Geolocator.getCurrentPosition(); + } + + void stopService() { + FlutterBackgroundService().invoke("stopService"); + } +} diff --git a/data/lib/service/location_service.dart b/data/lib/service/location_service.dart index fb7efda0..91525a34 100644 --- a/data/lib/service/location_service.dart +++ b/data/lib/service/location_service.dart @@ -39,4 +39,24 @@ class LocationService { return null; }); } + + Future saveCurrentLocation( + String userId, + double latitude, + double longitude, + int? recodedAt, + int? userState, + ) async { + final docRef = _locationRef(userId).doc(); + + final location = ApiLocation( + id: docRef.id, + user_id: userId, + latitude: latitude, + longitude: longitude, + created_at: recodedAt, + ); + + await docRef.set(location); + } } diff --git a/data/pubspec.yaml b/data/pubspec.yaml index 96929166..7d6dd439 100644 --- a/data/pubspec.yaml +++ b/data/pubspec.yaml @@ -25,6 +25,7 @@ dependencies: uuid: ^4.4.0 permission_handler: ^11.3.1 geolocator: ^12.0.0 + flutter_background_service: ^5.0.6 dev_dependencies: flutter_test: diff --git a/firebase-debug.log b/firebase-debug.log new file mode 100644 index 00000000..688daa9e --- /dev/null +++ b/firebase-debug.log @@ -0,0 +1,21 @@ +[debug] [2024-07-08T11:57:17.355Z] ---------------------------------------------------------------------- +[debug] [2024-07-08T11:57:17.358Z] Command: /usr/local/bin/firebase /home/kaushik/.cache/firebase/tools/lib/node_modules/firebase-tools/lib/bin/firebase init +[debug] [2024-07-08T11:57:17.358Z] CLI Version: 13.0.2 +[debug] [2024-07-08T11:57:17.358Z] Platform: linux +[debug] [2024-07-08T11:57:17.359Z] Node Version: v18.5.0 +[debug] [2024-07-08T11:57:17.359Z] Time: Mon Jul 08 2024 17:27:17 GMT+0530 (India Standard Time) +[debug] [2024-07-08T11:57:17.359Z] ---------------------------------------------------------------------- +[debug] +[debug] [2024-07-08T11:57:17.366Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] +[debug] [2024-07-08T11:57:17.367Z] > authorizing via signed-in user (kaushik.s@canopas.com) +[info] + ######## #### ######## ######## ######## ### ###### ######## + ## ## ## ## ## ## ## ## ## ## ## + ###### ## ######## ###### ######## ######### ###### ###### + ## ## ## ## ## ## ## ## ## ## ## + ## #### ## ## ######## ######## ## ## ###### ######## + +You're about to initialize a Firebase project in this directory: + + /home/kaushik/Clone projects/yourspace-flutter +