Skip to content

Commit

Permalink
Merge pull request #55 from dscdut/feat/SAFE/send_push_notification
Browse files Browse the repository at this point in the history
feat: send device token and realtime coordinate to firestore
  • Loading branch information
orangery-me authored Mar 12, 2024
2 parents c9233d2 + 7f590d8 commit 431142d
Show file tree
Hide file tree
Showing 16 changed files with 115 additions and 25 deletions.
6 changes: 5 additions & 1 deletion mobile/lib/bootstrap.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';

import 'package:easy_localization/easy_localization.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/widgets.dart';
Expand All @@ -11,6 +10,7 @@ import 'package:flutter_template/di/di.dart';
import 'package:flutter_template/flavors.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

typedef BootstrapBuilder = FutureOr<Widget> Function();

Expand Down Expand Up @@ -41,4 +41,8 @@ Future<void> initializeApp() async {
await FirebaseMessagingService.init();

Bloc.observer = AppBlocObserver();

FirebaseFirestore.instance.settings = const Settings(
persistenceEnabled: true, // offline support - store data locally in cache
);
}
5 changes: 0 additions & 5 deletions mobile/lib/common/helpers/firebase_messaging_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,4 @@ abstract final class FirebaseMessagingService {
}
});
}

Future<void> initNotifications() async {
// Send the token to your server
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
}
11 changes: 9 additions & 2 deletions mobile/lib/data/models/user_model.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions mobile/lib/data/services/permission/permission_service.dart

This file was deleted.

2 changes: 1 addition & 1 deletion mobile/lib/di/interceptors/app_interceptor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class AppInterceptor extends QueuedInterceptor {

// final String? accessToken = _authBox.get(HiveKeys.accessToken);
const String? accessToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NCwiZW1haWwiOiJjaGF1dGhpQGdtYWlsLmNvbSIsImlhdCI6MTcwOTk3ODMxNywiZXhwIjoxNzEwMDY0NzE3fQ.KAj7hPo_oZwHfFVvhYsqRlX6WbHSLztAnY4mxFF-V-k';
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NCwiZW1haWwiOiJjaGF1dGhpQGdtYWlsLmNvbSIsImlhdCI6MTcxMDIxNjcwOSwiZXhwIjoxNzEwMzAzMTA5fQ.NHr0KKT84YCCQ-xY3OBLhP5ry_73Fx0zg4-aibbEzqc';

if (accessToken != null) {
options.headers.addAll({
Expand Down
5 changes: 1 addition & 4 deletions mobile/lib/presentation/core/views/root_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ class _RootView extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
body: BlocBuilder<RootBloc, RootState>(
builder: (
context,
state,
) {
builder: (context, state) {
return SlideIndexedStack(
index: state.currentIndex,
children: const [HomePage(), NotificationPage(), ProfilePage()],
Expand Down
29 changes: 29 additions & 0 deletions mobile/lib/presentation/home/view/home.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
Expand Down Expand Up @@ -36,6 +38,8 @@ class HomeView extends StatefulWidget {

class _HomeViewState extends State<HomeView> {
late List<EmergencyCaseModel> emergencyCases;
final FirebaseMessaging messaging = FirebaseMessaging.instance;
final FirebaseFirestore db = FirebaseFirestore.instance;

final iconList = [
Assets.icons.navigationBar.map,
Expand All @@ -47,6 +51,31 @@ class _HomeViewState extends State<HomeView> {
];
int activeTab = 0;

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

// void listenToNewDeviceToken() async {
// final firstToken = await messaging.getToken();
// if (firstToken != null) {
// onPostNewDeviceToken(firstToken);
// }
// messaging.onTokenRefresh
// .listen((newToken) => onPostNewDeviceToken(newToken));
// }

// void onPostNewDeviceToken(String token) {
// final userID = context.read<AuthBloc>().state.user!.id;
// final data = {
// 'deviceToken': token,
// };
// db
// .collection('deviceToken')
// .doc('$userID')
// .set(data, SetOptions(merge: true));
// }

@override
Widget build(BuildContext context) {
return Scaffold(
Expand Down
40 changes: 38 additions & 2 deletions mobile/lib/presentation/map/bloc/position_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:equatable/equatable.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_template/common/constants/status.dart';
import 'package:flutter_template/data/models/emergency_case_model.dart';
import 'package:flutter_template/presentation/auth/auth.dart';
import 'package:flutter_template/presentation/emergency/bloc/manage/manage_emergency_case_bloc.dart';
import 'package:flutter_template/presentation/map/get_current_location.dart';
import 'package:flutter_template/presentation/map/get_markers.dart';
Expand All @@ -13,7 +16,8 @@ part 'position_event.dart';
part 'position_state.dart';

class PositionBloc extends Bloc<PositionEvent, PositionState> {
PositionBloc(this.manageEmergencyCaseBloc) : super(const PositionState()) {
PositionBloc(this.manageEmergencyCaseBloc, this.authBloc)
: super(const PositionState()) {
on<GetPosition>(_onGetPosition);
on<CurrentPositionChanged>(_onCurrentPositionChanged);
on<GetMarkersEvent>(_onGetMarkers);
Expand All @@ -24,12 +28,17 @@ class PositionBloc extends Bloc<PositionEvent, PositionState> {

emergencyCasesSubscription = manageEmergencyCaseBloc.stream
.listen((cases) => add(GetMarkersEvent(cases.emergencyCases)));
}

messaging.onTokenRefresh.listen((newToken) => postNewDeviceToken(newToken));
}
final ManageEmergencyCaseBloc manageEmergencyCaseBloc;
final AuthBloc authBloc;
late StreamSubscription emergencyCasesSubscription;
late StreamSubscription<Position> positionSubscription;

final FirebaseMessaging messaging = FirebaseMessaging.instance;
final FirebaseFirestore db = FirebaseFirestore.instance;

@override
Future<void> close() {
positionSubscription.cancel();
Expand All @@ -49,6 +58,14 @@ class PositionBloc extends Bloc<PositionEvent, PositionState> {
currentView: LatLng(position.latitude, position.longitude),
),
);
final data = {
'latitude': position.latitude,
'longitude': position.longitude,
};
db
.collection('coordinate')
.doc('${authBloc.state.user!.id}')
.set(data, SetOptions(merge: false));
} catch (e) {
emit(state.copyWith(status: Status.error, errorMessage: e.toString()));
}
Expand All @@ -58,6 +75,15 @@ class PositionBloc extends Bloc<PositionEvent, PositionState> {
CurrentPositionChanged event,
Emitter<PositionState> emit,
) {
final data = {
'latitude': event.position.latitude,
'longitude': event.position.longitude,
};
db
.collection('coordinate')
.doc('${authBloc.state.user!.id}')
.set(data, SetOptions(merge: false));

emit(
state.copyWith(
status: Status.isSuccess,
Expand All @@ -83,4 +109,14 @@ class PositionBloc extends Bloc<PositionEvent, PositionState> {
emit(state.copyWith(status: Status.error, errorMessage: e.toString()));
}
}

void postNewDeviceToken(String token) {
final data = {
'deviceToken': token,
};
db
.collection('deviceToken')
.doc('${authBloc.state.user!.id}')
.set(data, SetOptions(merge: true));
}
}
7 changes: 5 additions & 2 deletions mobile/lib/presentation/map/views/map_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_template/common/constants/status.dart';
import 'package:flutter_template/presentation/auth/auth.dart';
import 'package:flutter_template/presentation/emergency/bloc/manage/manage_emergency_case_bloc.dart';
import 'package:flutter_template/presentation/home/widgets/app_bar.dart';
import 'package:flutter_template/presentation/map/bloc/position_bloc.dart';
Expand All @@ -18,8 +19,10 @@ class MapPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) =>
PositionBloc(context.read<ManageEmergencyCaseBloc>()),
create: (context) => PositionBloc(
context.read<ManageEmergencyCaseBloc>(),
context.read<AuthBloc>(),
),
child: const MapView(),
);
}
Expand Down
2 changes: 1 addition & 1 deletion mobile/lib/presentation/notification/notification.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';

export 'bloc/notification_bloc.dart';
export 'bloc/notification/notification_bloc.dart';
export 'view/notification_view.dart';

class NotificationView extends StatelessWidget {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_template/presentation/notification/bloc/notification_bloc.dart';
import 'package:flutter_template/presentation/notification/bloc/notification/notification_bloc.dart';

class NotificationPage extends StatelessWidget {
const NotificationPage({super.key});
Expand Down
24 changes: 24 additions & 0 deletions mobile/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.1"
cloud_firestore:
dependency: "direct main"
description:
name: cloud_firestore
sha256: "8bfbb5a2edbc6052452326d60de0113fea2bcbf081d34a3f8e45c8b38307b31c"
url: "https://pub.dev"
source: hosted
version: "4.14.0"
cloud_firestore_platform_interface:
dependency: transitive
description:
name: cloud_firestore_platform_interface
sha256: "73ff438fe46028f0e19f55da18b6ddc6906ab750562cd7d9ffab77ff8c0c4307"
url: "https://pub.dev"
source: hosted
version: "6.1.0"
cloud_firestore_web:
dependency: transitive
description:
name: cloud_firestore_web
sha256: "232e45e95970d3a6baab8f50f9c3a6e2838d145d9d91ec9a7392837c44296397"
url: "https://pub.dev"
source: hosted
version: "3.9.0"
code_builder:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions mobile/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ dependencies:
flutter_polyline_points: ^2.0.0
google_maps_cluster_manager: ^3.1.0
geolocator: ^11.0.0
cloud_firestore: ^4.14.0

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 431142d

Please sign in to comment.