Instructions:

Enable Push notifications on each Platform, you can follow the instructions at the link:

  • Install package on it's latest version

  • Ensure the following dependencies constraints

    • permission_handler: ^10.0.2
  • iOS

    • Enable Push Notifications Capability under XCode
    • Enable Background Modes
      • Remote Notifications
      • Background fetch
    • Upload APN to Firebase Console
  • Android

  • Web

    • Configure VAPID key on Config
    • Create background service worker in root of project
      • firebase-messaging-sw.js
  • Create Configuration

    • Example lib/core/config/push_notifications_config.dart

      final FirePushNotificationsConfig pushNotificationsConfig = FirePushNotificationsConfig(
        registerDeviceTokenApiEndpoint: (params) {
          return Uri.parse(EnvironmentConfig.api_url + ApiEndpoints.devices());
        },
        removeDeviceTokenApiEndpoint: (params) {
          return Uri.parse(EnvironmentConfig.api_url + ApiEndpoints.devices());
        },
        removeDeviceRequestMapper: (request, info, params) {
          if (params?.containsKey("authToken") ?? false) {
            request.headers.addAll({
              "Authorization": params!["authToken"],
            });
            return request;
          }
          return request;
        },
      );
      
  • Create a wrapper container to setup some config and have better control

    • Example lib/core/presentation/containers/app_push_notifications_container.dart

      import 'package:flutter/material.dart';
      import 'package:flutter_bloc/flutter_bloc.dart';
      import 'package:flutter_gb_app_notifications/application/bloc/bloc.dart';
      import 'package:flutter_gb_authentication_basic/flutter_gb_authentication_basic.dart';
      import 'package:flutter_gb_fire_push_notifications/flutter_gb_fire_push_notifications.dart';
            
      class AppPushNotificationsContainer extends StatelessWidget {
        final Widget child;
        const AppPushNotificationsContainer({
          Key? key,
          required this.child,
        }) : super(key: key);
            
        @override
        Widget build(BuildContext context) {
          String? sessionToken;
          return FirePushNotificationsProvider(
            config: FirePushNotificationsBlocConfig(
              logEvents: true,
              paramBuilder: (event) {
                return event.maybeMap(
                  removeToken: (value) {
                    return {
                      "authToken": sessionToken,
                    };
                  },
                  orElse: () {
                    return {};
                  },
                );
              },
            ),
            child: AuthenticationBasicBlocListener(
              onLogout: (context, token) {
                sessionToken = token;
                context.read<FirePushNotificationsBloc>().removeToken();
              },
              child: Builder(
                builder: (context) {
                  return PushNotificationListener(
                      onEvent: (context, event) {
                        event.mapOrNull(
                          notificationReceived: (value) {
                            context.read<AppNotificationBloc>().getNotifications();
                            context.read<AppNotificationBloc>().getUnreadCount();
                          },
                        );
                      },
                      child: child);
                },
              ),
            ),
          );
        }
      }
      
    • Use that container to wrap your widget tree at your main widget tree, we recommend wrapping a widget that is behind an authentication guard