Implement Background Sync Polling with Workmanager
This commit is contained in:
1 parent
8c80bc0033
commit
14eefa1062
5 files changed
+121
No files matched your search
@@ -0,0 +1,63 @@
|
||||
import 'dart:math' as math;
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:workmanager/workmanager.dart';
|
||||
import 'notification_service.dart';
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void callbackDispatcher() {
|
||||
Workmanager().executeTask((task, inputData) async {
|
||||
try {
|
||||
// 1. Retrieve the saved base URL and Auth Token
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final baseUrl = prefs.getString('server_url');
|
||||
if (baseUrl == null) return true; // No server known, wait till next run
|
||||
|
||||
const storage = FlutterSecureStorage();
|
||||
final token = await storage.read(key: 'jwt_token');
|
||||
if (token == null) return true; // Not logged in
|
||||
|
||||
// 2. Fetch recent notifications from server
|
||||
final dio = Dio(BaseOptions(
|
||||
baseUrl: baseUrl,
|
||||
connectTimeout: const Duration(seconds: 5),
|
||||
receiveTimeout: const Duration(seconds: 5),
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
));
|
||||
|
||||
final response = await dio.get('/notifications/recent');
|
||||
final list = (response.data as List).cast<Map<String, dynamic>>();
|
||||
|
||||
if (list.isNotEmpty) {
|
||||
// 3. Find the last seen notification ID
|
||||
final highestOldId = prefs.getInt('last_seen_notification_id') ?? 0;
|
||||
|
||||
// Find new ones
|
||||
final newNotes = list.where((e) => (e['id'] as int) > highestOldId).toList();
|
||||
|
||||
if (newNotes.isNotEmpty) {
|
||||
final notificationService = NotificationService();
|
||||
await notificationService.initialize(); // Ensure it's ready in this isolate
|
||||
|
||||
// 4. Show local notification for each new one
|
||||
for (var note in newNotes) {
|
||||
await notificationService.showNotification(
|
||||
title: note['title'] ?? 'New Notification',
|
||||
body: note['message'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
// 5. Update highest seen ID in prefs
|
||||
final newHighestId = list.map((e) => e['id'] as int).reduce(math.max);
|
||||
await prefs.setInt('last_seen_notification_id', math.max(highestOldId, newHighestId));
|
||||
}
|
||||
}
|
||||
|
||||
return Future.value(true);
|
||||
} catch (e) {
|
||||
print('Background fetch failed: $e');
|
||||
return Future.value(false); // Retries on false
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -12,7 +12,9 @@ import 'ui/screens/splash/splash_screen.dart';
|
||||
import 'core/theme/app_theme.dart'; // Add this import
|
||||
import 'core/constants/app_colors.dart';
|
||||
import 'core/services/notification_service.dart';
|
||||
import 'core/services/background_sync_service.dart';
|
||||
import 'ui/shared/widgets/inactivity_wrapper.dart';
|
||||
import 'package:workmanager/workmanager.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@@ -47,6 +49,22 @@ void main() async {
|
||||
|
||||
await NotificationService().initialize();
|
||||
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||
Workmanager().initialize(
|
||||
callbackDispatcher,
|
||||
isInDebugMode: false,
|
||||
);
|
||||
// Register periodic task
|
||||
Workmanager().registerPeriodicTask(
|
||||
"1",
|
||||
"background_sync_task",
|
||||
frequency: const Duration(minutes: 15),
|
||||
constraints: Constraints(
|
||||
networkType: NetworkType.connected,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
runApp(const ProviderScope(child: TisRmsApp()));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../domain/repositories/notification_repository.dart';
|
||||
import '../../domain/entities/notification_model.dart';
|
||||
import '../../core/services/notification_service.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'dart:math' as math;
|
||||
|
||||
final notificationRepositoryProvider = Provider<NotificationRepository>((ref) {
|
||||
@@ -52,6 +53,12 @@ class NotificationNotifier extends AsyncNotifier<List<NotificationModel>> {
|
||||
}
|
||||
}
|
||||
|
||||
if (list.isNotEmpty) {
|
||||
final highestId = list.map((e) => e.id).reduce(math.max);
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setInt('last_seen_notification_id', highestId);
|
||||
}
|
||||
|
||||
state = AsyncData(list);
|
||||
} catch (e, st) {
|
||||
state = AsyncError(e, st);
|
||||
|
||||
@@ -1549,6 +1549,38 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.0"
|
||||
workmanager:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: workmanager
|
||||
sha256: "065673b2a465865183093806925419d311a9a5e0995aa74ccf8920fd695e2d10"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.0+3"
|
||||
workmanager_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: workmanager_android
|
||||
sha256: "9ae744db4ef891f5fcd2fb8671fccc712f4f96489a487a1411e0c8675e5e8cb7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.0+2"
|
||||
workmanager_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: workmanager_apple
|
||||
sha256: "1cc12ae3cbf5535e72f7ba4fde0c12dd11b757caf493a28e22d684052701f2ca"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.1+2"
|
||||
workmanager_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: workmanager_platform_interface
|
||||
sha256: f40422f10b970c67abb84230b44da22b075147637532ac501729256fcea10a47
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.1+1"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -60,6 +60,7 @@ dependencies:
|
||||
pdf: ^3.12.0
|
||||
intl: ^0.20.3
|
||||
flutter_local_notifications: ^17.2.2
|
||||
workmanager: ^0.9.0+3
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in new issue
Block a user