Awesome Notifications

repository·master·Indexed 21 days ago

https://github.com/rafaelsetragni/awesome_notifications

A Flutter plugin for creating highly customizable local and push notifications. It supports real-time event handling, scheduled notifications with second-level precision, and various layouts including big picture, media, and progress bars (Android only). The plugin is designed to be a comprehensive replacement for other notification libraries and is incompatible with flutter_local_notifications.

Tokens
33.3K
Snippets
56
Records
87
Agent score
74%

What's inside awesome_notifications

  1. Overview of Awesome Notifications

    master

    Awesome Notifications is a Flutter plugin designed to engage users through highly customizable local and push notifications. It allows developers to create notifications with images, sounds, emoticons, buttons, and various layouts.

    Key capabilities include:

    • Real-time events: Listen to notification lifecycle events (created, displayed, dismissed, or tapped) directly in Flutter code.
    • Scheduled notifications: Schedule notifications with second-level precision, including repeated schedules.
    • Customization: Support for translations and diverse notification layouts.
    • Platform Support: Works for both local and remote push notifications.
  2. Translate notification content with NotificationLocalization

    master

    The NotificationLocalization class allows you to provide localized strings for notification components like title, body, summary, largeIcon, bigPicture, and buttonLabels.

    To use localization:

    1. Use setLocalization(languageCode: '...') to set the active language (e.g., 'en', 'pt-br').
    2. Use getLocalization() to retrieve the current language code.
    3. When calling createNotification, pass a localizations map where keys are language codes and values are NotificationLocalization objects.
    await AwesomeNotifications().createNotification(
      content: NotificationContent(
        id: id,
        channelKey: 'basic_channel',
        title: 'Default English Title',
        body: 'Default English Body',
        // ... other content fields
      ),
      localizations: {
        'pt-br' : NotificationLocalization(
            title: 'Este título está em português!',
            body: 'Corpo traduzido!',
            summary: 'Resumo em português',
            bigPicture: 'asset://assets/images/pt-br.jpg',
            largeIcon: 'asset://assets/images/brazilian.jpg',
            buttonLabels: {
              'AGREED1': 'Eu concordo!',
            }
        ),
      }
    );
  3. Configure notification time zones

    master

    Time zone behavior depends on the identifier used:

    • UTC: Triggered at the same time globally; unaffected by daylight savings.
    • Local (Fixed Offset): e.g., "GMT-07:00". Unaffected by daylight savings.
    • Local (Named Region): e.g., "Europe/Lisbon". Affected by daylight savings rules.

    You can retrieve the device's current time zone identifiers using:

    • AwesomeNotifications().getLocalTimeZoneIdentifier()
    • AwesomeNotifications().getUtcTimeZoneIdentifier()
  4. Schedule notifications using different scheduling classes

    master

    To schedule a notification, pass one of the following scheduling classes to the schedule property of the createNotification method:

    • NotificationCalendar: Schedules a notification for when specific date components match. If a component (like second) is set to null, any value for that component is valid. Only one value per component is allowed.
    • NotificationInterval: Schedules a notification to repeat at a specific time interval (e.g., every 60 seconds).
    • NotificationAndroidCrontab: (Android only) Schedules notifications based on a crontab rule or a list of precise dates with second precision.

    All scheduling classes support these properties:

    • timeZone: The time zone for the schedule (e.g., "UTC", "America/Los_Angeles", "Europe/London").
    • allowWhileIdle: Whether to send the notification even during low battery/critical device states.
    • repeats: Whether the schedule should repeat after being displayed.
    // Example: Interval scheduling
    await AwesomeNotifications().createNotification(
      content: NotificationContent(
        id: 1,
        channelKey: 'scheduled',
        title: 'Every minute',
        body: 'Repeating notification',
      ),
      schedule: NotificationInterval(interval: 60, timeZone: localTimeZone, repeats: true),
    );
  5. Understand the philosophy of Awesome Notifications

    master

    Awesome Notifications is designed to simplify notification implementation by providing a feature-rich API that abstracts device-specific complexities. The library follows these core principles:

    • Consistent Delivery: Notifications sent while the app is inactive are recorded and delivered once the app restarts and listeners are initialized.
    • Device-Specific Adaptation: The plugin automatically omits features (like LED lights) if the hardware does not support them, preventing crashes or errors.
    • Cross-Platform Emulation: It attempts to provide a consistent experience by emulating Android's notification channel behavior on iOS, and emulating iOS's app badge management on other platforms.
    • Focus on Content: The API is designed so developers can focus on what the notification says rather than the technical nuances of different operating systems.
  6. Configure Notification Importance levels

    master

    Notification importance is defined as a hierarchy. The importance level determines behaviors like sound, heads-up visibility, and visual intrusion.

    Important Note: The importance level of a channel can only be defined the first time the channel is created; it cannot be changed afterwards.

    Available levels:

    • Max: Makes a sound and appears as a heads-up notification.
    • Higher: Shows everywhere, makes noise and peeks. May use full-screen intents.
    • Default: Shows everywhere, makes noise, but does not visually intrude.
    • Low: Shows in the shade (and potentially in the status bar), but is not audibly intrusive.
    • Min: Only shows in the shade, below the fold.
    • None: Disables the respective channel.
  7. Choose a Notification Action Type

    master

    You can customize how a user interacts with a notification by selecting an action type. For silent action types, always use the await keyword to prevent the Dart isolate from shutting down before the work completes.

    Action Types

    • Default: Forces the app to the foreground when the notification is tapped.
    • SilentAction: Runs on the main thread without forcing the app to the foreground. Can accept visual elements. Can be interrupted if the main app is terminated.
    • SilentBackgroundAction: Runs in a background exclusive Dart isolate without forcing the app to the foreground. Does not accept visual elements.
    • KeepOnTop: Fires the action without closing the notification tray and without bringing the app to the foreground.
    • DisabledAction: Closes the notification in the tray without firing an event.
    • DismissAction: Dismisses the notification and fires onDismissActionReceivedMethod. Ignores the autoDismissible property.
    • InputField (Deprecated): Use the requireInputText property instead to open a dialog for text responses.
  8. Understand Notification Events and Delivery

    master

    Notification events are delivered only after calling the setListeners method. Note that events may not always be delivered at the exact moment they occur, depending on the app lifecycle and platform.

    Available Event Methods

    • onNotificationCreatedMethod (optional): Fires when a notification is created.
    • onNotificationDisplayedMethod (optional): Fires when a notification is displayed on the system status bar.
    • onActionReceivedMethod (required): Fires when a notification is tapped by the user. Note: This method fires immediately across all platforms and lifecycles.
    • onDismissedActionReceivedMethod (optional): Fires when a notification is dismissed (subject to OS restrictions).

    Delivery Conditions by Platform

    PlatformApp in ForegroundApp in BackgroundApp Terminated
    AndroidImmediateImmediateEvents stored until app is in Foreground/Background
    iOSImmediateEvents stored until app is in ForegroundEvents stored until app is in Foreground
  9. How to handle notification actions in background isolates

    master

    When handling silentAction or silentBackgroundAction events, you may be running in a separate Dart Isolate that lacks a valid BuildContext. To perform UI operations (like navigation) in the main isolate, use IsolateNameServer with ReceivePort and SendPort.

    Pattern:

    1. Create a ReceivePort during initialization in the main isolate.
    2. Register the port with a unique name using IsolateNameServer.registerPortWithName.
    3. In your onActionReceivedMethod (which might run in a background isolate), check if you have access to the main isolate. If not, look up the SendPort by name and send the action data to it.
    4. The listener on the ReceivePort in the main isolate then receives the data and performs the UI/navigation logic.
    // 1. In your initialization (Main Isolate)
    ReceivePort port = ReceivePort();
    IsolateNameServer.registerPortWithName(port, 'notification_actions');
    port.listen((var serializedData) async {
        final receivedAction = ReceivedAction().fromMap(serializedData);
        _handleActionReceived(receivedAction);
    });
    
    // 2. In your static listener (Background Isolate)
    static Future<void> onActionReceivedMethod(ReceivedAction received) async {
      if (!_initialized) {
        SendPort? uiSendPort = IsolateNameServer.lookupPortByName('notification_actions');
        if (uiSendPort != null) {
          uiSendPort.send(received.toMap());
          return;
        }
      }
      await _handleActionReceived(received);
    }
  10. Understand Notification Permission Levels

    master

    Permissions in Awesome Notifications operate at three distinct levels of granularity:

    1. Device level: Global settings applied to all apps on the device (e.g., Do Not Disturb, Battery Saver).
    2. Application level: Global settings applied to all notifications within your specific app, regardless of the channel.
    3. Channel level: Settings that apply only to notifications sent through a specific notification channel.
  11. Request notification permissions

    master

    Before sending notifications, you should check if permissions are already granted. If not, request them. It is highly recommended to show a user-friendly dialog explaining why you need permission before calling requestPermissionToSendNotifications() to ensure a good user experience.

    AwesomeNotifications().isNotificationAllowed().then((isAllowed) {
      if (!isAllowed) {
        // Show a friendly dialog here first!
        AwesomeNotifications().requestPermissionToSendNotifications();
      }
    });