displayNotification method

Future<void> displayNotification(
  1. Map<String, dynamic> data
)

Display a notification from FCM data payload

Expected data fields:

  • title: Notification title
  • body: Notification body
  • imageUrl: (optional) Image URL to display
  • button: (optional) Action button text
  • target: Navigation target (screen/url)
  • navigate_to_screen: Screen name to navigate to
  • navigate_to_url: URL to open
  • callbackUrl: URL to track notification click

Implementation

Future<void> displayNotification(Map<String, dynamic> data) async {
  if (!_initialized) {
    debugPrint('NotificationDisplayService not initialized, skipping notification display');
    return;
  }

  debugPrint('=== DISPLAYING NOTIFICATION ===');
  debugPrint('Data payload: $data');

  final String title = data['title'] ?? 'Notification';
  final String body = data['body'] ?? '';
  final String? imageUrl = data['imageUrl'];
  final String? buttonText = data['button'];

  debugPrint('Title: $title');
  debugPrint('Body: $body');
  debugPrint('ImageUrl: $imageUrl');
  debugPrint('Button: $buttonText');

  // For iOS: Register dynamic category if button text is provided
  String? categoryId;
  if (Platform.isIOS && buttonText != null && buttonText.isNotEmpty) {
    // Generate the same category ID that the service extension would use
    categoryId = 'RELEVA_DYNAMIC_${buttonText.hashCode}';
    debugPrint('iOS: Using dynamic category ID: $categoryId');

    // Register the category with iOS native code for foreground notifications
    try {
      await _platformChannel.invokeMethod('registerNotificationCategory', {
        'buttonText': buttonText,
      });
      debugPrint('iOS: Registered notification category with button: $buttonText');
    } catch (e) {
      debugPrint('iOS: Error registering notification category: $e');
    }
  }

  // Generate unique notification ID
  final int notificationId = DateTime.now().millisecondsSinceEpoch.remainder(100000);

  // Download image if provided
  final String? largeIconPath = await _downloadAndSaveImage(imageUrl);
  final String? bigPicturePath = await _downloadAndSaveImage(imageUrl);

  // Android notification details
  AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'releva_notifications',
    'Releva Notifications',
    channelDescription: 'Notifications from Releva SDK',
    importance: Importance.high,
    priority: Priority.high,
    largeIcon: largeIconPath != null ? FilePathAndroidBitmap(largeIconPath) : null,
    styleInformation: bigPicturePath != null
        ? BigPictureStyleInformation(
            FilePathAndroidBitmap(bigPicturePath),
            hideExpandedLargeIcon: true,
          )
        : null,
  );

  // Add action button if provided
  if (buttonText != null && buttonText.isNotEmpty) {
    androidDetails = AndroidNotificationDetails(
      'releva_notifications',
      'Releva Notifications',
      channelDescription: 'Notifications from Releva SDK',
      importance: Importance.high,
      priority: Priority.high,
      largeIcon: largeIconPath != null ? FilePathAndroidBitmap(largeIconPath) : null,
      styleInformation: bigPicturePath != null
          ? BigPictureStyleInformation(
              FilePathAndroidBitmap(bigPicturePath),
              hideExpandedLargeIcon: true,
            )
          : null,
      actions: [
        AndroidNotificationAction(
          'action_1',
          buttonText,
          showsUserInterface: true,
        ),
      ],
    );
  }

  // iOS notification details
  DarwinNotificationDetails iosDetails = const DarwinNotificationDetails(
    presentAlert: true,
    presentBadge: true,
    presentSound: true,
  );

  // Add category identifier for iOS if button text is provided
  if (Platform.isIOS && categoryId != null) {
    iosDetails = DarwinNotificationDetails(
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
      categoryIdentifier: categoryId,
    );
  }

  final NotificationDetails details = NotificationDetails(
    android: androidDetails,
    iOS: iosDetails,
  );

  // Convert data to payload string for later retrieval
  final String payload = _mapToPayload(data);

  await _notificationsPlugin.show(
    notificationId,
    title,
    body,
    details,
    payload: payload,
  );

  debugPrint('Displayed notification: $title - $body');
}