Coding Frontend
Coding Frontend

Reputation: 183

flutter_local_notifications plugin not showing the big image in notification

I need to make like this notification

enter image description here

My Output code

enter image description here

my Pubspec.yaml file. I am using latest version of flutter_local_notifications

  flutter_local_notifications: ^9.2.0

This is my Notification Controller code

import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:image/image.dart' as image;
import 'package:path_provider/path_provider.dart';

class NotificationService {
  static final NotificationService _notificationService =
      NotificationService._internal();

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  factory NotificationService() {
    return _notificationService;
  }

  NotificationService._internal();
  Future<void> init(
      Function(int, String?, String?, String?)?
          onDidReceiveLocalNotification) async {
    const AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/launcher_icon');

    final IOSInitializationSettings initializationSettingsIOS =
        IOSInitializationSettings(
      requestAlertPermission: false,
      requestBadgePermission: false,
      requestSoundPermission: false,
      onDidReceiveLocalNotification:
          (int id, String? title, String? body, String? payload) async {},
    );
    final InitializationSettings initializationSettings =
        InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );
    await flutterLocalNotificationsPlugin.initialize(
      initializationSettings,
      onSelectNotification: (String? payload) async {
        if (payload != null) {
          print('notification payload: $payload');
        }
      },
    );
  }

  Future selectNotification(String? payload) async {
    print('selectNotification: $payload');
  }

  Future<String> _downloadAndSaveFile(String url, String fileName) async {
    final Directory? directory = await getExternalStorageDirectory();
    final String filePath = '${directory!.path}/$fileName.png';
    final http.Response response = await http.get(Uri.parse(url));
    final File file = File(filePath);
    await file.writeAsBytes(response.bodyBytes);
    return filePath;
  }

  Future showNotify({
    required String body,
    required String image,
  }) async {
    final String largeIconPath = await _downloadAndSaveFile(
      'https://via.placeholder.com/48x48',
      'largeIcon',
    );
    final String bigPicturePath = await _downloadAndSaveFile(
      image,
      'bigPicture',
    );

    await flutterLocalNotificationsPlugin.show(
      123,
      'New Buisness Sutra Updated',
      body,
      NotificationDetails(
        android: AndroidNotificationDetails(
          'big text channel id',
          'big text channel name',
          ongoing: true,
          priority: Priority.max,
          largeIcon: FilePathAndroidBitmap(largeIconPath),
          channelDescription: 'big text channel description',
          styleInformation: BigPictureStyleInformation(
            FilePathAndroidBitmap(bigPicturePath),
            hideExpandedLargeIcon: false,
            contentTitle: 'overridden <b>big</b> content title',
            htmlFormatContentTitle: true,
            summaryText: 'summary <i>text</i>',
            htmlFormatSummaryText: true,
          ),
        ),
      ),
      payload: 'data',
    );
  }
}

I initialized the firebase and notification on my main.dart file


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  if (!kIsWeb) {
    await Firebase.initializeApp();
    firebaseCloudMessagingListeners();
    await NotificationService().init();
  }
  runApp(const MyApp());
}

firebaseCloudMessagingListeners() {
  FirebaseMessaging.onBackgroundMessage(_messageHandler);
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    print(message);
    _messageHandler(message);
  });
  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    print("Message opened");
  });
}

Future<void> _messageHandler(RemoteMessage message) async {
  Map<String, dynamic> data = message.data;
  print(data);
  await NotificationService().showNotify(
    body: data["body"],
    image: data["image"],
  );
}

The firebase_messaging plugin works fine. The problem is with the big picture on the notification from flutter_local_notifications. I download the image by using path_provider and http. also this image succesfully downloaded on my app External storage directory. But not shown on the notification

/storage/emulated/0/Android/data/in.myapp.dhrona/files/largeIcon.png /storage/emulated/0/Android/data/in.myapp.dhrona/files/bigIcon.png

Any solutions for this issue

Upvotes: 6

Views: 12842

Answers (4)

HuyDragun
HuyDragun

Reputation: 99

I use example code of flutter_local_notifications and success show Notification with large icon or bigPicture. In below example I only show largeIcon, if you want to show bigPicture, you need to use styleInformation instead.

Future<String> _downloadAndSaveFile(String url, String fileName) async {
final Directory directory = await getApplicationDocumentsDirectory();
final String filePath = '${directory.path}/$fileName';
final http.Response response = await http.get(Uri.parse(url));
final File file = File(filePath);
await file.writeAsBytes(response.bodyBytes);
return filePath;}

Future<void> _showLocalNotification(CustomNotification notification) async {
if (!notification.image!.isNullOrEmpty) {
  _flutterLocalNotificationsPlugin.show(
    notification.id,
    notification.title,
    notification.body,
    NotificationDetails(
        android: AndroidNotificationDetails(
          _channel.id,
          _channel.name,
          channelDescription: _channel.description,
          importance: Importance.max,
          priority: Priority.high,
          enableVibration: true,
          color: AppColor.colorPrimary,
          icon: '@drawable/ic_vota',
          largeIcon: FilePathAndroidBitmap(await _downloadAndSaveFile(
              notification.image ?? '', 'largeIcon')),
        ),.....

And the payload look like this

{
"to": "fcm-token",
"data": {
    "body": "",
    "title": "",
    "imageUrl": ""
},
"notification": {
    "body": "",
    "title": ""
}}

If you want to use both largeIcon & bigPicture, watch this

final String largeIconPath =
    await _downloadAndSaveFile('online image URL', 'largeIcon');
final String bigPicturePath = await _downloadAndSaveFile(
    'online image URL', 'bigPicture');

final BigPictureStyleInformation bigPictureStyleInformation =
 BigPictureStyleInformation(FilePathAndroidBitmap(bigPicturePath),
        largeIcon: FilePathAndroidBitmap(largeIconPath));

final AndroidNotificationDetails androidNotificationDetails =
    AndroidNotificationDetails(
        'big text channel id', 'big text channel name',
        channelDescription: 'big text channel description',
        styleInformation: bigPictureStyleInformation);

Upvotes: 0

Harmeet Singh
Harmeet Singh

Reputation: 620

Although the answer by @Vignesh works, here are some improvements to that answer:

  • response is not used in the example
  • there is no need to set the "largeIcon" property with the same image data as the big image because it will show the same image two times in the notification when the notification is expanded.

the final answer should look like this:

final http.Response response = await http.get(Uri.parse(imageUrl));
        bigPictureStyleInformation = BigPictureStyleInformation(
            ByteArrayAndroidBitmap.fromBase64String(base64Encode(response.bodyBytes)));

      flutterLocalNotificationsPlugin.show(
          notification.hashCode,
          notification.title ?? 'APP_NAME',
          notification.body,
          NotificationDetails(
            android: AndroidNotificationDetails(
              channel.id,
              channel.name,
              channelDescription: channel.description,
              styleInformation: bigPictureStyleInformation,
              // other properties...
            ),
          )
      );

Upvotes: 9

Vignesh
Vignesh

Reputation: 160

To show network image,

    final http.Response response = await http.get(Uri.parse(URL));
    BigPictureStyleInformation bigPictureStyleInformation =
        BigPictureStyleInformation(
      ByteArrayAndroidBitmap.fromBase64String(base64Encode(image)),
      largeIcon: ByteArrayAndroidBitmap.fromBase64String(base64Encode(image)),
    );
    flutterLocalNotificationsPlugin.show(
      Random().nextInt(1000),
      title,
      description,
      NotificationDetails(
        android: AndroidNotificationDetails(channel.id, channel.name,
            channelDescription: channel.description,
            importance: Importance.high,
            styleInformation: bigPictureStyleInformation),
      ),
    );

To show local image,

    final String filePath = '${directory.path}/$fileName';
    final BigPictureStyleInformation bigPictureStyleInformation =
        BigPictureStyleInformation(FilePathAndroidBitmap(filePath),
            largeIcon: FilePathAndroidBitmap(filePath));
    flutterLocalNotificationsPlugin.show(
      Random().nextInt(1000),
      title,
      description,
      NotificationDetails(
        android: AndroidNotificationDetails(channel.id, channel.name,
            channelDescription: channel.description,
            importance: Importance.high,
            styleInformation: bigPictureStyleInformation),
      ),
    );

Upvotes: 6

mario francois
mario francois

Reputation: 1371

With AwesomeNotifications I don't need to download. I just give the url like below:

  Future<void> showNotificationChatMessage(
      RemoteMessage message, MyMessage myMessage) async {
    final chatId = message.data['chatId'];
    NotificationContent? notificationContent;
    if (myMessage.type == MyMessageType.text ||
        myMessage.replyType == MyMessageReplyType.text) {
      notificationContent = NotificationContent(
          id: 10,
          channelKey: 'basic_channel',
          title: message.data['title'].toString(),
          body: message.data['body'].toString(),
          payload: {'chatId': chatId.toString()});
    } else if (myMessage.type == MyMessageType.image ||
        myMessage.replyType == MyMessageReplyType.image) {
      notificationContent = NotificationContent(
          id: 11,
          channelKey: 'big_picture',
          title: message.data['title'].toString(),
          body: 'Image',
          bigPicture: myMessage.message,
          showWhen: true,
          displayOnBackground: true,
          payload: {'chatId': chatId.toString()},
          notificationLayout: NotificationLayout.BigPicture);
    }
    if (notificationContent != null) {
      AwesomeNotifications().createNotification(content: notificationContent);
    }
  }

Upvotes: 1

Related Questions