flutter_gb_app_notifications 1.2.1 copy "flutter_gb_app_notifications: ^1.2.1" to clipboard
flutter_gb_app_notifications: ^1.2.1 copied to clipboard

A comprehensive solution for handling in-app notifications in Flutter, including fetching, displaying, managing states (read, unread, archived), and customizable UI components.

Flutter GB App Notifications #

Flutter Dart Version

A comprehensive, flexible, and robust solution for handling in-app notifications in Flutter applications. This package seamlessly handles fetching, displaying, and managing notification states (read, unread, archived). It offers flexible configuration options and customizable UI components to quickly integrate a fully functional notification center into your app.


Table of Contents #


Features #

  • Ready-to-use Notification Center UI: Provides list templates and full-page templates.
  • Swipe Actions: Swipe to mark as read or to archive (flutter_slidable built-in).
  • Unread Badge Icon: Automatically updating bell icon with a notification count.
  • Custom Metadata Parsing: Type-safe custom metadata loading and parsing.
  • Flexible Data Sources: Highly customizable endpoint builders to match any backend shape.
  • Robust State Management: Built-in BLoC implementation manages fetching, polling or error states gracefully.

Installation #

Add the following to your pubspec.yaml file:

dependencies:
  flutter_gb_app_notifications: ^0.17.0

Run flutter pub get to install the package.

Note: Ensure you have flutter_slidable (version ^2.0.0 or higher) as a dependency in your project, as it's used for swipe actions in the notification list.


Configuration (AppNotificationConfig) #

The AppNotificationConfig class is central to configuring the library's behavior, especially how it interacts with your backend API. You must register an instance of AppNotificationConfig using the dependency injection setup.

Here's an example of how to configure AppNotificationConfig:

import 'package:flutter_gb_app_notifications/flutter_gb_app_notifications.dart';
import 'package:http/http.dart'; // For Response and Request types

final AppNotificationConfig appNotificationConfig = AppNotificationConfig(
  getListApiEndpoint: (params) {
    // Endpoint to fetch a list of notifications
    return Uri.parse("https://api.example.com/notifications")
        .replace(queryParameters: (params ?? {})..addAll({"sort": "-createdAt"}));
  },
  getUnreadCountApiEndpoint: (params) {
    // Endpoint to fetch the count of unread notifications
    return Uri.parse("https://api.example.com/notifications/unread-count")
        .replace(queryParameters: params);
  },
  markAsReadCompleteApiEndpoint: (notification) {
    // Optional: Endpoint to mark a specific notification as read
    return Uri.parse("https://api.example.com/notifications/${notification.id}/read");
  },
  archiveApiEndpoint: (notification) {
    // Optional: Endpoint to archive a specific notification
    return Uri.parse("https://api.example.com/notifications/${notification.id}/archive");
  },
  archiveAllApiEndpoint: () {
    // Optional: Endpoint to archive all notifications
    return Uri.parse("https://api.example.com/notifications/archive-all");
  },
  getListResponseParser: (response) {
    // Optional: Custom parser for the list of notifications API response
    // Example: return (json.decode(response.body) as List).map((e) => AppNotification.fromJson(e)).toList();
    return []; // Implement your parsing logic here
  },
  getCountResponseParser: (response) {
    // Optional: Custom parser for the unread count API response
    // Example: return json.decode(response.body)['count'] as int;
    return 0; // Implement your parsing logic here
  },
  metadataMapper: (map) {
    // Optional: Custom mapper for notification metadata.
    // Use this to deserialize custom metadata types based on a 'type' field or similar.
    // Example:
    // String? type = map["type"];
    // switch (type) {
    //   case "followed_user_creation":
    //     return FollowedUserCreationNotificationMetadataModel.fromMap(map);
    //   default:
    //     return AppNotificationMetadataModel.fromMap(map);
    // }
    return AppNotificationMetadataModel.fromMap(map); // Default or custom logic
  },
  markAsReadRequestMapper: (request, notification) {
    // Optional: Customize the request for marking a notification as read
    // return request.copyWith(headers: {'X-Custom-Header': 'value'});
    return request;
  },
  archiveRequestMapper: (request, notification) {
    // Optional: Customize the request for archiving a notification
    // return request.copyWith(body: json.encode({'status': 'archived'}));
    return request;
  },
  archiveAllRequestMapper: (request) {
    // Optional: Customize the request for archiving all notifications
    // return request.copyWith(method: 'POST');
    return request;
  },
);

Configuration Options #

Field Type Description
getUnreadCountApiEndpoint Uri Function(Map<String, dynamic>? params) Required. Provides the API endpoint to fetch the unread notification count.
getListApiEndpoint Uri Function(Map<String, dynamic>? params) Required. Provides the API endpoint to fetch the list of notifications.
markAsReadCompleteApiEndpoint Uri Function(AppNotification)? Optional. API endpoint to mark a specific notification as read.
archiveApiEndpoint Uri Function(AppNotification)? Optional. API endpoint to archive a specific notification.
archiveAllApiEndpoint Uri Function()? Optional. API endpoint to archive all notifications.
getListResponseParser List<AppNotification> Function(Response)? Optional. A custom function to parse the API response for the list of notifications.
getCountResponseParser int Function(Response)? Optional. A custom function to parse the unread notification count.
metadataMapper NotificationMetadataMapper? Optional. A custom function to map raw JSON metadata to your custom AppNotificationMetadata.
markAsReadRequestMapper BaseRequest Function(Request, AppNotification)? Optional. Customize the HTTP request before sending it to mark as read.
archiveRequestMapper BaseRequest Function(Request, AppNotification)? Optional. Customize the HTTP request before sending it to archive.
archiveAllRequestMapper BaseRequest Function(Request)? Optional. Customize the HTTP request before sending it to archive all.

Custom Notification Metadata #

You can extend AppNotificationMetadata to define custom metadata for your notifications. This is useful for handling different types of notifications with specific data. For serialization, it's recommended to use built_value.

  1. Define your custom metadata class:

    // lib/domain/entities/custom_app_notification_metadata.dart
    abstract class FollowedUserCreationNotificationMetadata implements AppNotificationMetadata {
      String? get resourceId;
      String? get resourceName;
      String? get ownerUsername;
    }
    
  2. Create a built_value model for your metadata:

    // lib/infrastructure/models/custom_app_notification_metadata_model.dart
    import 'dart:convert';
    import 'package:built_value/built_value.dart';
    import 'package:built_value/serializer.dart';
    import 'package:flutter_gb_app_notifications/flutter_gb_app_notifications.dart';
    
    part 'custom_app_notification_metadata_model.g.dart';
    
    abstract class FollowedUserCreationNotificationMetadataModel
        implements
            FollowedUserCreationNotificationMetadata,
            Built<FollowedUserCreationNotificationMetadataModel, FollowedUserCreationNotificationMetadataModelBuilder> {
      FollowedUserCreationNotificationMetadataModel._();
      factory FollowedUserCreationNotificationMetadataModel(
              [void Function(FollowedUserCreationNotificationMetadataModelBuilder) updates]) =
          _$FollowedUserCreationNotificationMetadataModel;
    
      static FollowedUserCreationNotificationMetadataModel fromMap(Map<String, dynamic> map) {
        // Ensure you have a global serializers instance accessible, e.g., appSerializers
        return appSerializers.deserializeWith(FollowedUserCreationNotificationMetadataModel.serializer, map)!;
      }
    
      static Serializer<FollowedUserCreationNotificationMetadataModel> get serializer =>
          _$followedUserCreationNotificationMetadataModelSerializer;
    }
    
  3. Register your custom metadata model with your project's Serializers:

    // lib/infrastructure/models/serializers.dart
    @SerializersFor([
      AppNotificationMetadata,
      FollowedUserCreationNotificationMetadataModel,
    ])
    final Serializers appSerializers = (_$appSerializers.toBuilder()).build();
    
  4. Implement metadataMapper in AppNotificationConfig: As shown in the AppNotificationConfig example, provide a metadataMapper function that inspects the raw notification map and returns the appropriate custom AppNotificationMetadata instance.


Presentation Widgets API #

The library provides several widgets to help you display and manage notifications in your UI.

GBNotificationBadgeBuilder #

A widget that displays an icon (e.g., a bell) with an unread notification count badge. It automatically fetches and updates the unread count.

import 'package:flutter/material.dart';
import 'package:flutter_gb_app_notifications/flutter_gb_app_notifications.dart';

class MyNotificationIcon extends StatelessWidget {
  const MyNotificationIcon({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GBNotificationBadgeBuilder.bellIcon(
      size: 30,
      iconColor: Colors.blue,
      badgeColor: Colors.red,
      onTap: () {
        // Navigate to the notifications page
      },
    );
  }
}

AppNotificationBuilder #

A BlocBuilder wrapper that rebuilds its child widget whenever the AppNotificationState changes. Useful for custom UIs.

AppNotificationBuilder(
  builder: (context, state) {
    if (state.isLoading) return const CircularProgressIndicator();
    if (state.notifications.isEmpty) return const Text('No notifications');

    return ListView.builder(
      itemCount: state.notifications.length,
      itemBuilder: (context, index) {
        final notification = state.notifications[index];
        return ListTile(title: Text(notification.title));
      },
    );
  },
)

GBAppNotificationsListTemplate #

A pre-built widget that displays a list of notifications with swipe-to-action (mark as read, archive) functionality, pull-to-refresh, and empty/error states.

GBAppNotificationsListTemplate(
  style: AppNotificationsListTemplateStyle(
    enableArchive: true,
    enableMarkAsRead: true,
    onItemTap: (notification) {
      print('Tapped on notification: ${notification.title}');
    },
    onEmptyBuilder: (context, constraints) {
      return const Center(child: Text('You have no new alerts.'));
    },
  ),
)

GBNotificationPageTemplate #

A full-page template for displaying notifications, embedding GBAppNotificationsListTemplate and adding a customizable AppBar.

GBNotificationPageTemplate(
  titlePage: 'My App Notifications',
  backgroundColor: Colors.grey[100],
  titleColor: Colors.black,
  style: AppNotificationsListTemplateStyle(
    enableArchive: true,
  ),
);

Customizing List UI (AppNotificationsListTemplateStyle) #

AppNotificationsListTemplateStyle provides numerous configurations.

Field Type Description
enableMarkAsRead bool Enables swipe-to-mark-as-read action. (Default: true)
enableArchive bool Enables swipe-to-archive action. (Default: true)
enableItemSeparator bool Renders a separator between list items. (Default: true)
itemContentBuilder AnimatedStateListItemBuilder<AppNotification>? A custom builder for the content of each notification item.
separatorBuilder AnimatedStateListItemBuilder<AppNotification>? A custom builder for the item separator.
onItemTap void Function(AppNotification)? Callback when a notification item is tapped.
autoReadOnTap bool Automatically marks notification as read upon tap. (Default: true)
onEmptyBuilder Widget Function(BuildContext, BoxConstraints)? Custom builder for the empty list state.
filterCallback bool Function(AppNotification)? Filter callback for the notification list.
headerBuilder Widget Function(BuildContext)? Custom builder for a header widget (must return a Sliver).

Dependency Injection #

The library requires get_it for dependency injection. Call configureAppNotificationInjection to register necessary services.

import 'package:flutter_gb_stack_base/flutter_gb_stack_base.dart';
import 'package:get_it/get_it.dart';
import 'package:flutter_gb_app_notifications/flutter_gb_app_notifications.dart';

final getItNotifications = GetIt.instance;

Future<void> configureAppNotificationInjection(
  AppEnvironment environment,
  AppNotificationConfig config,
) async {
  if (!getItNotifications.isRegistered<AppNotificationConfig>()) {
    getItNotifications.registerSingleton<AppNotificationConfig>(config);
  }

  getItNotifications.registerSingletonAsync<NotificationService>(
    () async {
      return NotificationServiceImpl(
        httpClient: getItNotifications(),
        notificationConfig: config,
      );
    },
    dependsOn: [
      if (AppEnvironment.test != environment) IHttpClient,
    ],
  );

  await getItNotifications.isReady<NotificationService>();
}

Usage:

Initialize dependencies early in your application lifecycle.

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Register your core dependencies (e.g., IHttpClient)
  // configureCoreDependencies();

  // Configure App Notifications
  await configureAppNotificationInjection(
    AppEnvironment.development,
    appNotificationConfig, // Your AppNotificationConfig instance
  );

  runApp(const MyApp());
}

Contributing #

Contributions are welcome! Please create an issue or submit a pull request if you find a bug or want to propose an enhancement. Ensure tests run successfully and maintain the current code style.

0
likes
130
points
46
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A comprehensive solution for handling in-app notifications in Flutter, including fetching, displaying, managing states (read, unread, archived), and customizable UI components.

Homepage

License

BSD-2-Clause (license)

Dependencies

built_value, collection, dartz, flutter, flutter_bloc, flutter_gb_built_utils, flutter_gb_stack_base, flutter_gb_ui_kit, flutter_slidable, freezed_annotation, get_it, http, logger

More

Packages that depend on flutter_gb_app_notifications