backgroundHandler static method

Future<void> backgroundHandler(
  1. RemoteMessage message
)

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:

  1. Checks if the message contains a SuperFCM delivery ID
  2. Retrieves the subscription from SharedPreferences to get the app ID
  3. If a valid subscription is found, initializes managers and attempts an immediate delivery status update
  4. 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');
    }
  }
}