Skip to content

Commit

Permalink
refactor: Improve message sending logic in ChatCubit
Browse files Browse the repository at this point in the history
  • Loading branch information
MoErn878 committed Jun 4, 2024
1 parent 59e71a2 commit f343e6b
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 147 deletions.
69 changes: 13 additions & 56 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,14 @@

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">

<service
android:name="id.flutter.flutter_background_service.BackgroundService"
android:foregroundServiceType="location"
/>

<service
android:enabled="true"
android:exported="true"
android:name=".BackgroundService"
android:stopWithTask="false"
/>

<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">

<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>

<receiver
android:name=".WatchdogReceiver"
android:enabled="true"
android:exported="true"
/>

<receiver
android:name=".BootReceiver"
android:enabled="true"
android:exported="true">

<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>

</receiver>
android:name="${applicationName}">

<!-- -->
<activity
android:name=".MainActivity"
android:exported="true"
Expand All @@ -72,27 +35,21 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />

<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
See README(https://goo.gl/l4GJaQ) for more. -->
<!-- <meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" /> -->
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. See README(https://goo.gl/6BKBk7) for more. -->
<!-- <meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id" /> -->
</application>
android:name="firebase_messaging_auto_init_enabled"
android:value="false" />
<meta-data
android:name="firebase_analytics_collection_enabled"
android:value="false" />

</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility?hl=en and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
Expand Down
55 changes: 55 additions & 0 deletions lib/core/notifications/messaging.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:logger/logger.dart';

initializeMessaging() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;

NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);

Logger().i('User granted permission: ${settings.authorizationStatus}');

await messaging.setAutoInitEnabled(true);

// You may set the permission requests to "provisional" which allows the user to choose what type
// of notifications they would like to receive once the user receives a notification.
final notificationSettings =
await messaging.requestPermission(provisional: true);

// For apple platforms, ensure the APNS token is available before making any FCM plugin API calls
final apnsToken = await messaging.getAPNSToken();
if (apnsToken != null) {
// APNS token is available, make FCM plugin API requests...
Logger().i('APNS Token: $apnsToken');
}

messaging.onTokenRefresh.listen((fcmToken) {
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new
// token is generated.

Logger().i('FCM Token: $fcmToken');
}).onError((err) {
// Error getting token.
Logger().e('Error getting FCM token: $err');
});

final fcmToken = await messaging.getToken();
Logger().i('FCM Token: $fcmToken');

FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

}

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print("Handling a background message: ${message.messageId}");
}
7 changes: 5 additions & 2 deletions lib/features/main/chat/logic/cubit/chat_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,13 @@ class ChatCubit extends Cubit<ChatState> {

// Send message to the chat channel
void sendMessage(int receiverDoctorId) {
if (messageController.text.isNotEmpty) {
var message = messageController.text.trim();
if (message.isNotEmpty) {
// Create the message
_chatRepo.sendMessageToMessagingChannel(
receiverDoctorId, messageController.text);
receiverDoctorId,
message,
);

// Clear the input field
messageController.clear();
Expand Down
97 changes: 8 additions & 89 deletions lib/init.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:logger/logger.dart';
import 'core/di/dependency_injection.dart';
import 'core/notifications/messaging.dart';
import 'core/shared_preferences/shared_preferences_service.dart';
import 'dart:async';
import 'package:flutter_background_service_android/flutter_background_service_android.dart';
import 'firebase_options.dart';

Future<void> init() async {
// Required for async calls in `main`
WidgetsFlutterBinding.ensureInitialized();

// Firebase initialization
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);

// Initialize get it
setupGetIt();

Expand All @@ -27,102 +32,16 @@ Future<void> init() async {
// Initialize deep linking
await deepLinking();

// Initialize background service
await initializeBackgroundAndForegroundService();
}

Future<void> sharedPreferencesInit() async {
await SharedPrefsService.init();
// EntrySharedPrefs.clearEntry();
}

Future<void> firebaseMessagingInit() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging messaging = FirebaseMessaging.instance;
messaging.getToken().then((value) {
Logger().i(value);
});

FirebaseMessaging.onMessage.listen((RemoteMessage event) {
Logger().i("message received");
Logger().i(event.notification!.body);
});
FirebaseMessaging.onMessageOpenedApp.listen((message) {
Logger().i('Message clicked!');
});
initializeMessaging();
}

/// Foreground and Background
Future<void> initializeBackgroundAndForegroundService() async {
final service = FlutterBackgroundService();

await service.configure(
androidConfiguration: AndroidConfiguration(
onStart: onStart,
autoStart: false,
isForegroundMode: true,
// notificationChannelId: 'my_foreground',
// initialNotificationContent: 'running',
foregroundServiceNotificationId: 888,
),
iosConfiguration: IosConfiguration(
autoStart: true,
onForeground: onStart,
onBackground: onIosBackground,
),
);
}

/// Deep linking
Future<void> deepLinking() async {}

///---------------------------------------- main.dart ----------------------------------------//
@pragma('vm:entry-point')
Future<bool> onIosBackground(ServiceInstance service) async {
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
return true;
}

@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
DartPluginRegistrant.ensureInitialized();
if (service is AndroidServiceInstance) {
service.on('setAsForeground').listen((event) {
service.setAsForegroundService();
});
service.on('setAsBackground').listen((event) {
service.setAsBackgroundService();
});
}
service.on('stopService').listen((event) {
service.stopSelf();
});

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

// bring to foreground
Timer.periodic(const Duration(seconds: 1), (timer) async {
if (service is AndroidServiceInstance) {
if (await service.isForegroundService()) {
flutterLocalNotificationsPlugin.show(
0,
'This is foreground',
'${DateTime.now()}',
const NotificationDetails(
android: AndroidNotificationDetails(
"notificationChannelId",
'MY FOREGROUND SERVICE',
icon: 'ic_bg_service_small',
ongoing: true,
),
),
);
}
}
});
}
Future<void> deepLinking() async {}
2 changes: 2 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'pharmalink_app.dart';
import 'init.dart';



void main() async {
await init();
runApp(PharmalinkApp());
Expand Down

0 comments on commit f343e6b

Please sign in to comment.