backgroundHandler static method
Processes messages received while the app is in the background or terminated. This function attempts to make an immediate API request to update delivery status rather than just caching it for later processing.
The function:
- Checks if the message contains a SuperFCM delivery ID
- Retrieves the subscription from SharedPreferences to get the app ID
- If a valid subscription is found, initializes managers and attempts an immediate delivery status update
- If the immediate update fails or no subscription is found, falls back to direct database caching for later processing
Parameters:
message
: The Firebase RemoteMessage containing the notification data
Implementation
static Future<void> backgroundHandler(RemoteMessage message) async {
logger.d("Background message received: ${message.data}");
// Check if this is a SuperFCM message
if (message.data.containsKey(kDeliveryKey)) {
final deliveryId = message.data[kDeliveryKey];
final prefs = SharedPreferences.getInstance();
// Try to load subscription from SharedPreferences to get the appId
final subscription = await _getSubscriptionFromCache(prefs);
if (subscription != null && subscription.appId != null) {
try {
// Create minimal configuration using the subscription's appId
final config = SuperFCMConfig(
appId: subscription.appId!,
cacheOnOffline: true,
logLevel: LogLevel.debug,
);
// Initialize required managers
await CacheManager.instance.initialize(config);
await RequestManager.instance.initialize(config);
// Attempt immediate delivery status update
// RequestManager will handle network connectivity and cache if offline
logger.d(
'Attempting immediate delivery status update for: $deliveryId');
await RequestManager.instance.request(
RequestType.patch,
'deliveries/$deliveryId',
{'status': kMessageStatusReceived},
true, // Enable caching as fallback
);
// Clean up resources
await RequestManager.instance.dispose();
await CacheManager.instance.dispose();
return;
} catch (e) {
logger.e('Error while attempting direct delivery status update: $e');
// Continue to fallback caching mechanism
}
}
// Fallback: Direct database caching if RequestManager approach wasn't possible
Database? db;
try {
db = await openDatabase(
kCacheDatabaseName,
version: kCacheDatabaseVersion,
singleInstance: false,
);
// Insert the request directly without using CacheManager
final timestamp = DateTime.now().millisecondsSinceEpoch;
await db.insert('requests', {
'type': RequestType.patch.toString(),
'endpoint': 'deliveries/$deliveryId',
'data': json.encode({'status': kMessageStatusReceived}),
'timestamp': timestamp,
});
logger.d(
'Background delivery status update cached for later processing: $deliveryId',
);
} catch (e) {
logger.e('Error in background message handler fallback: $e');
} finally {
// Always close this dedicated connection
await db?.close();
logger.v('Background handler completed, database closed');
}
}
}