notix 0.0.13 copy "notix: ^0.0.13" to clipboard
notix: ^0.0.13 copied to clipboard

Effortlessly manage notifications on Android and iOS with Notix with Firestore integration.

Notix #

Effortlessly manage and customize notifications on Android and iOS in your Flutter app with Notix.

Table of Contents #

Installation #

Add the following line to your pubspec.yaml file:

dependencies:
  notix: ^x.y.z

Replace x.y.z with the latest version of Notix from pub.dev.

Getting Started #

1. Initialize Notix #

Initialize Notix with your configuration, such as Firebase Cloud Messaging (FCM) settings and notification channels. This step is essential before using Notix in your app.

import 'package:Notix/Notix.dart';

void main() async {
  await Notix.init(
    configs: NotixConfig(
      firebaseMessagingKey: 'YOUR_FCM_API_KEY',
      icon: 'notification_icon',
      // Add more configuration options here
    ),
  );
}

2. Get clientNotificationId #

To receive notifcation using FCM, the targeted user must have clientNotificationId which is unique id generated by the FCM for each device. The user may have mutiple clients notifications ids depending on the number of devices the user logged in.

Notix provide an easy way to get that id and you need to store it within the user data so you can targetting that user later when you want to send him notification.

You can get the token either by calling Notix.getToken() or by listening to the Notix.onTokenRefresh stream.

/// Get the FCM token
Notix.getToken().then((value) {
  if (value == null) return;
  MyDatasource.addNewFCMToken(
    userId: 'user_id',
    clientNotificationId: value,
  );
});

/// Listen to the FCM tokens
Notix.onTokenRefresh.listen((event) {
  MyDatasource.addNewFCMToken(
    userId: 'user_id',
    clientNotificationId: value,
  );
});

3. Send Notifications #

Send notifications to your app users with ease. You can customize the content, channel, and behavior of each notification.

void sendNotification() {
  NotixMessage notification = NotixMessage(
    title: 'New Message',
    body: 'You have a new message.',
    clientNotificationIds: ['unique_id'],
    // Add more notification details here
  );

  Notix.push(notification, addToHistory: true);
}

4. View notifications history to users #

Assuming you are familiar with the Firebase Firestore, the notifications are stored in the firestore so you can display them in the notifcations screen with in your app.

Notix have provided an easy Firestore Query and let the rest on you so you can customize the screen in the way you want. I suggest to use kr_paginate_firestore to build the ui using this Query as follow:

1- First, Notix need to know the current user id by defining it as follow:

  await Notix.init(
    configs: NotixConfig(
      // ...
      currentUserId: () => _authController.currentUser.id,
    ),
  );

2- Setting the receiver user id when sending notification to him:

final notification = NotixMessage(
  targetedUserId: 'user_id',
  // ...
);

3- Display the notifcations history

import 'package:kr_paginate_firestore/paginate_firestore.dart';

KrPaginateFirestore(
  itemBuilder: (context, documentSnapshots, i) {
    NotixMessage not =
        documentSnapshots.elementAt(i).data() as NotixMessage;
    return NotificationCard(not);
  },
  query: Notix.firebaseQuery(),
  itemBuilderType: PaginateBuilderType.listView,
  isLive: true,
  onEmpty: Center(
      child: Padding(
    padding: const EdgeInsets.only(bottom: 140),
    child: const EmptyWidget(text: 'No notifications yet'),
  )),
  initialLoader: const Column(
    children: [
      NotificationCardEmpty(),
      NotificationCardEmpty(),
      NotificationCardEmpty(),
    ],
  ),
  bottomLoader: const NotificationCardEmpty(),
)

Do not forget to mark notification as seen when the user interact with notification or when the user leave your notifications screen.

Notix.markAsSeen('notification_id');

Also you have the ability to push the notification to the user without adding it to the notifications history by setting the addToHistory to false.

Notix.push(notification, addToHistory: false);

Advanced Usage #

1. Notification Channels #

Notix supports the creation and management of notification channels on Android. You can define channels with different behaviors, such as sound, vibration, or LED colors.

NotixChannel channel = NotixChannel(
  id: 'chat',
  name: 'Chat',
  description: 'Chat Channel',
  playSound: true,
  showBadge: true,
  enableVibration: true,
  enableLights: true,
  ledColor: Colors.blue,
  sound: 'custom_sound.mp3',
  importance: NotixImportance.high,
);

// Add the channel to the configuration
NotixConfig configs = NotixConfig(
  channels: [
    channel,
    // other channels
  ],
  // ...
);

await Notix.push(
  NotixMessage(
    // ...
    channel: 'chat',
  ),
);

Also you can group notifications by defining the group channels as follow:

final channel = NotixChannel(
  id: 'chat',
  name: 'Chat',
  // ...
  // set groupId
  groupId: 'chat_group',
);

final groupChannel = NotixGroupChannel(
  id: 'chat_group',
  name: 'Chat',
  description: 'Chat channel',
),

// Add the channel to the configuration
NotixConfig configs = NotixConfig(
  channels: [channel],
  groupChannels: [groupChannel],
  // ...
);

await Notix.push(
  NotixMessage(
    title: 'New Message',
    body: 'You have a new message.',
    clientNotificationIds: ['unique_id'],
    channel: 'chat',
  ),
);

2. Handle Push Notifications Events #

Handle incoming notifications and customize the behavior when a user interacts with them. You can listen to various notification events and take actions accordingly.

You can handle the notifications event either by:

1- Setting the onRecievedNotification and onSelectNotification in the configs as follow:

await Notix.init(
  configs: NotixConfig(
    firebaseMessagingKey: 'YOUR_FCM_API_KEY',
    icon: 'notification_icon',
    onSelectNotification: (notification){
      if(notification.type == 'message'){
          Navigator.of(context).pushNamed('/chat')
      }
    },
    onRecievedNotification: (notification){
      print(notification.payload);
    },
  ),
);

2- Or by listening to the eventsStream as follow:

import 'package:Notix/Notix.dart';

void main() {
  Notix.eventsStream.listen((event) {
    switch (notificationReceivedEvent.type) {
      case EventType.receiveNotification:
        // Handle single notification reception event.
        break;
      case EventType.notificationTap:
        // Handle notification tap event.
        break;
      case EventType.notificationAdd:
        // Handle notification addition event.
        break;
    }
  });
}

3. Customize notification #

Currently the all the notifcations have one style which is the title and optional body. Images and custom layout is not supprted yet. However, you can configure the notification icon, sound, and importance.

The notification take the general configuration by related channel if assigned. You can ovveride these configuration by changing assigning them with the NotixMessage model as follow:

final notification = NotixMessage(
          // ...
          importance: NotixImportance.high,
          isSeen: true,
          playSound: true,
        )

4. Send Notifcations to Multiple Devices #

FCM topic messaging allows you to send a message to multiple devices that have opted in to a particular topic. To push notifcation to topic set the topic id instead of the clientNotificationIds as follow:

await Notix.push(
  NotixMessage(
    title: 'New Message',
    body: 'You have a new message.',
    topic: 'topic_id',
    channel: 'chat',
  ),
);

Then you need to subscribe to the topic:

await Notix.subscibeToTopic('topic_id');

also you can unsubscribe from specific topic:

await Notix.unsubscibeToTopic('topic_id');

or unsubscribe from all topics:

await Notix.unsubscribeFromAll();

5. Schedule Notifications #

To schedule notifications to show at secific time, all you need to add scheduleTime in the NotixMessage model:

final notification = NotixMessage(
      // ...
      scheduleTime: ScheduleTime(
        sendAt: DateTime(2024, 2, 1),
        timeZone: 'Asia/Baghdad', // Optional (The device time zone is default value)
      ),
);

6. Show Notifications According to Specific Condition #

You can determine to show or ignore the push notification according tou your logic. For example, you have chat app and you don't want to push notification if the receiver already in the same chat room.

await Notix.init(
  // ...
  canShowNotification: (notification) {
    return currentOpenedChat != notification.payload?['chatId'];
  },
);

7. Add Payload to Notification #

Assuming you have Invitation model and you want to send the invite data with the notification and then retrieve this data for the receiver side. Use the payload parameter to assign your model data and use the toMap and fromMap method to convert the data.

class InviteModel {
  final String id;
  final DateTime date;
  final String title;

  InviteModel({
    required this.id,
    required this.date,
    required this.title,
  });

  InviteModel.fromMap(Map<String, dynamic> map)
      : id = map['id'],
        date = DateTime.parse(map['date']),
        title = map['title'];

  Map<String, dynamic> toMap() => {
        'id': id,
        'date': date.toString(),
        'title': title,
      };
}


Notix.init(
  configs: NotixConfig(
    // ...
    onSelectNotification: (notification) {
      switch (notification.payload?['type']) {
          case 'invite':
            {
              final invite = InviteModel.fromMap(notification.payload!);
              Navigator.push(
                Get.context!,
                MaterialPageRoute(
                  builder: (context) => InviteScreen(invite),
                ),
              );
            }
            break;
        case 'otherType':
          // ...
          break;
        default:
      }
    },
  ),
);  

final invite = InviteModel(
  id: '1',
  date: DateTime.now(),
  title: 'Invite',
);

Notix.push(NotixMessage(
  // ...
  payload: {
    ...invite.toMap(),
    'type': 'invite',
  },
));

8. Custom Database #

Don't like firestore? You still can use Notix with your own datastore. You can extends the NotixDatastore as follow:

class CustomNotixDatasource extends NotixDatastore {

  // Your datastore
  final yourDatastore;

  @override
  Future<NotixMessage?> get(String id) async {
    Map<String, dynamic> data = await yourDatastore.getNotification(id);
    return NotixMessage.fromMap(data);
  }

  @override
  Future<void> delete(String id) async {
    await yourDatastore.deletetNotification(id);
  }

  @override
  Future<void> save(NotixMessage notification) async {
      await yourDatastore.deletetNotification(notification.toMap);
  }

  @override
  Future<void> markAsSeen(String notificationId) async {
    await yourDatastore.markNotificationAsSeen(id);
  }

  @override
  Future<void> markAllAsSeen([String? userId]) async {
    await yourDatastore.markAllNotificationsAsSeen(id);
  }

  @override
  Query<NotixMessage> query([String? userId]) =>
      throw UnimplementedError('The Firestore data source is disabled');

  @override
  Stream<int> get unseenCountStream =>
      throw UnimplementedError('The Firestore data source is disabled');
}

Then you need to add your custom datastore in the init method:

await Notix.init(
  configs: NotixConfig(
    datasourceConfig: CustomNotixDatasource(),
  )
)
1
likes
130
pub points
0%
popularity

Publisher

unverified uploader

Effortlessly manage notifications on Android and iOS with Notix with Firestore integration.

Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (LICENSE)

Dependencies

cloud_firestore, dio, firebase_core, firebase_messaging, flutter, flutter_local_notifications, flutter_timezone, timezone

More

Packages that depend on notix