diff --git a/lib/background/background.dart b/lib/background/background.dart index 994e9b78..ca0bf7c6 100644 --- a/lib/background/background.dart +++ b/lib/background/background.dart @@ -22,13 +22,19 @@ Future serviceMain(ServiceInstance service) async { final Map> activeSubscriptions = {}; final nostrService = NostrService(); - final db = await openMostroDatabase('events.db'); - final eventStore = EventStorage(db: db); + // Register event handlers BEFORE awaiting database open to avoid + // losing events (e.g. 'start' invoked by FCM handler during db init). service.on('app-foreground-status').listen((data) { isAppForeground = data?['is-foreground'] ?? isAppForeground; }); + service.on('fcm-wake').listen((data) { + // Service is already running with active subscriptions. + // Nostr subscriptions will automatically receive new events. + logger?.d('FCM wake signal received - subscriptions already active'); + }); + service.on('start').listen((data) async { if (data == null) return; @@ -50,6 +56,9 @@ Future serviceMain(ServiceInstance service) async { service.invoke('service-ready', {}); }); + final db = await openMostroDatabase('events.db'); + final eventStore = EventStorage(db: db); + service.on('update-settings').listen((data) async { if (data == null) return; diff --git a/lib/services/fcm_service.dart b/lib/services/fcm_service.dart index fbaa7a6e..5e313200 100644 --- a/lib/services/fcm_service.dart +++ b/lib/services/fcm_service.dart @@ -1,9 +1,11 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_background_service/flutter_background_service.dart'; +import 'package:mostro_mobile/data/models/enums/storage_keys.dart'; import 'package:mostro_mobile/services/logger_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:mostro_mobile/firebase_options.dart'; @@ -45,8 +47,39 @@ Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { final service = FlutterBackgroundService(); final isRunning = await service.isRunning(); - if (!isRunning) { + if (isRunning) { + // Service is already running — signal it that FCM detected new activity + service.invoke('fcm-wake', {}); + } else { + // Service is dead — start it and send settings await sharedPrefs.setBool('fcm.pending_fetch', true); + await service.startService(); + + final settingsJson = await sharedPrefs.getString( + SharedPreferencesKeys.appSettings.value, + ); + if (settingsJson != null) { + Map? settings; + try { + settings = jsonDecode(settingsJson) as Map?; + } catch (e) { + debugPrint('FCM: Failed to decode settings: $e'); + } + + // Wait briefly for service to initialize (FCM handlers must complete quickly) + const maxWait = Duration(seconds: 3); + final deadline = DateTime.now().add(maxWait); + while (!(await service.isRunning())) { + if (DateTime.now().isAfter(deadline)) break; + await Future.delayed(const Duration(milliseconds: 100)); + } + + if (await service.isRunning() && settings != null) { + service.invoke('start', { + 'settings': settings, + }); + } + } } } catch (e) { debugPrint('FCM: background service error: $e');