react-native-push-notification icon indicating copy to clipboard operation
react-native-push-notification copied to clipboard

Group notifications

Open FranciscoCHT opened this issue 5 years ago • 11 comments

Question

Hello! How does group and groupSummary work? I recently migrated from React Native Firebase V5, to this library to handle local notifications. In RNFirebase I had to create and display 2 notifications, one that should be only for summary group and and another to handle the notification itself and asign it to the group.

In this library, the option groupSummary is present, but it isn't seem to be working for me, or maybe I'm doing it wrong. I'm creating/displaying the notification with the code below. I want to group notifications in separated groups. Should I use two notifications, like on RNFirebase? If so, in what format should they be?

Another thing that I realized is that there is not groupAlertBehavior option, to handle a notification that will be only for the group summary.

Thanks!

PushNotification.localNotification({
            /* Android Only Properties */
            autoCancel: true, // (optional) default: true
            largeIcon: "", // (optional) default: "ic_launcher". Use "" for no large icon.
            smallIcon: "ic_notification", // (optional) default: "ic_notification" with fallback for "ic_launcher". Use "" for default small icon.
            vibrate: true,
            vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000
            tag: "approved", // (optional) add tag to message
            group: "approved", // (optional) add group to message
            groupSummary: true, // (optional) set this notification to be the group summary for a group of notifications, default: false
            priority: "max", // (optional) set notification priority, default: high
            importance: "max", // (optional) set notification importance, default: high
            channelId: DEFAULT_CHANNEL_ID, // (optional) custom channelId, if the channel doesn't exist, it will be created with options passed above (importance, vibration, sound). Once the channel is created, the channel will not be update. Make sure your channelId is different if you change these options. If you have created a custom channel, it will apply options of the channel.

            /* iOS and Android properties */
            title: message.data.title, // (optional)
            message: message.data.body, // (required)
            playSound: true, // (optional) default: true
            soundName: "default", // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played)
            number: message.data.badge, // (optional) Valid 32 bit integer specified as string. default: none (Cannot be zero)
});

FranciscoCHT avatar Aug 11 '20 01:08 FranciscoCHT

Nevermind, found a workaround this myself. 🤣

FranciscoCHT avatar Aug 11 '20 06:08 FranciscoCHT

@FranciscoCHT It would be great if you provide working code here, i also need to integrate group notification, but not working for me.

sufyan297 avatar Aug 11 '20 06:08 sufyan297

Ended up following the same logic as I did with RNFirebase V5 (Android only).

I created two PushNotification.localNotification, one for the notification itself, and another for creating the groupSummary that will group the others notifications.

The problem with this was that onNotification it will show 2 popup notifications at the same time (one grouped and the one arriving). In Android, this is fixed by adding the parameter groupAlertBehavior which allows to set to silent the groupSummary notification, but it hasn't been added to this library yet.

So, since I hadn't this parameter, and wanted only to show the arriving notification as popup, and the group notification silent, I had to create a special channel, with PushNotification.createChannel, and configured it to be silent, then assigned it to the groupSummary notification.

PushNotification.createChannel({
            channelId: POPUP_CHANNEL_ID,
            channelName: POPUP_CHANNEL_NAME,
            channelDescription: POPUP_CHANNEL_DESC,
            soundName: "default",
            importance: 5,     // <- POPUP NOTIFICATION CHANNEL
            vibrate: true,
});
PushNotification.createChannel({
            channelId: SILENT_CHANNEL_ID,
            channelName: SILENT_CHANNEL_NAME,
            channelDescription: SILENT_CHANNEL_DESC,
            importance: 2,     // <- SILENT NOTIFICATION CHANNEL
            vibrate: false,
});

Then assigned it to the 2 local notifications. The POPUP CHANNEL to the arriving notification, and the SILENT CHANNEL to the groupSummary notification.

/* POPUP NOTIFICATION */
PushNotification.localNotification({
            /* Android Only Properties */
            autoCancel: true,
            smallIcon: "ic_notification",
            vibrate: true,
            group: message.data.groupName,
            channelId: POPUP_CHANNEL_ID,  // <- ASSIGN POPUP CHANNEL CREATED

            /* iOS and Android properties */
            title: message.data.title,
            message: message.data.body,
            playSound: true,
            soundName: "default",
            number: message.data.badge,
});

/* GROUP SUMMARY NOTIFICATION */
PushNotification.localNotification({
            /* Android Only Properties */
            autoCancel: true, 
            smallIcon: "ic_notification",
            group: message.data.groupName, 
            groupSummary: true,          // <- REQUIRED IN GROUP SUMMARY NOTIFICATION
            channelId: SILENT_CHANNEL_ID, // <- ASSIGN SILENT CHANNEL CREATED

            /* iOS and Android properties */
            id: groupId[message.data.groupName], // REQUIRED, HAS TO BE A NUMBER
            message: "", //REQUIRED
});

The group summary notification has to have the same ID in each group you want to create, otherwise it will group in different notifications, and has to be a number, otherwise it'll not work.

This should group notifications that share the same group parameter, and mantain silent the group notifications. I know that the creation of another channel isn't ideal, and I don't know if there is a simpler solution, but feel free to share any finds! 😄

FranciscoCHT avatar Aug 11 '20 07:08 FranciscoCHT

@FranciscoCHT I have found a better solution without the need of extra channels. Using the following code you should not need an extra channel:

// POP UP NOTIFICATION
        PushNotification.localNotification({
            data: notification,
            showWhen: true, // (optional) default: true
            autoCancel: true, // (optional) default: true
            smallIcon: '@drawable/ic_stat_name', // (optional) default: "ic_notification" with fallback for "ic_launcher". Use "" for default small icon.
            subText: notification.subText, // (optional) default: none
            color: '#8000ff', // (optional) default: system default
            vibrate: true, // (optional) default: true
            vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000
            group: notification.channel_id, // (optional) add group to message
            ongoing: false, // (optional) set whether this is an "ongoing" notification
            priority: "high", // (optional) set notification priority, default: high
            visibility: "private", // (optional) set notification visibility, default: private
            importance: "high", // (optional) set notification importance, default: high
            allowWhileIdle: false, // (optional) set notification to work while on doze, default: false
            ignoreInForeground: false, // (optional) if true, the notification will not be visible when the app is in the foreground (useful for parity with how iOS notifications appear)
            channelId: notification.channel_id, // (optional) custom channelId, if the channel doesn't exist, it will be created with options passed above (importance, vibration, sound). Once the channel is created, the channel will not be update. Make sure your channelId is different if you change these options. If you have created a custom channel, it will apply options of the channel.
            onlyAlertOnce: false, //(optional) alert will open only once with sound and notify, default: false
            messageId,
            invokeApp: true, // (optional) This enable click on actions to bring back the application to foreground or stay in background, default: true
            alertAction: "view", // (optional) default: view
            category: "", // (optional) default: empty string
            title: notification.title, // (optional)
            message: notification.body, // (required)
            userInfo: {}, // (optional) default: {} (using null throws a JSON value '<null>' error)
            playSound: true, // (optional) default: true
            soundName: "default", // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played)
        });

// GROUP SUMMARY 
        PushNotification.localNotification({
            channelId: notification.channel_id,
            id: this.ids[notification.channel_id],
            group: notification.channel_id,
            subText: notification.subText,
            smallIcon: '@drawable/ic_stat_name',
            color: '#8000ff',
            groupSummary: true,
             title: notification.title, 
            message: notification.body,
            data: notification,

        })

OmarBasem avatar Aug 27 '20 09:08 OmarBasem

@FranciscoCHT I have found a better solution without the need of extra channels. Using the following code you should not need an extra channel:

// POP UP NOTIFICATION
        PushNotification.localNotification({
            data: notification,
            showWhen: true, // (optional) default: true
            autoCancel: true, // (optional) default: true
            smallIcon: '@drawable/ic_stat_name', // (optional) default: "ic_notification" with fallback for "ic_launcher". Use "" for default small icon.
            subText: notification.subText, // (optional) default: none
            color: '#8000ff', // (optional) default: system default
            vibrate: true, // (optional) default: true
            vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000
            group: notification.channel_id, // (optional) add group to message
            ongoing: false, // (optional) set whether this is an "ongoing" notification
            priority: "high", // (optional) set notification priority, default: high
            visibility: "private", // (optional) set notification visibility, default: private
            importance: "high", // (optional) set notification importance, default: high
            allowWhileIdle: false, // (optional) set notification to work while on doze, default: false
            ignoreInForeground: false, // (optional) if true, the notification will not be visible when the app is in the foreground (useful for parity with how iOS notifications appear)
            channelId: notification.channel_id, // (optional) custom channelId, if the channel doesn't exist, it will be created with options passed above (importance, vibration, sound). Once the channel is created, the channel will not be update. Make sure your channelId is different if you change these options. If you have created a custom channel, it will apply options of the channel.
            onlyAlertOnce: false, //(optional) alert will open only once with sound and notify, default: false
            messageId,
            invokeApp: true, // (optional) This enable click on actions to bring back the application to foreground or stay in background, default: true
            alertAction: "view", // (optional) default: view
            category: "", // (optional) default: empty string
            title: notification.title, // (optional)
            message: notification.body, // (required)
            userInfo: {}, // (optional) default: {} (using null throws a JSON value '<null>' error)
            playSound: true, // (optional) default: true
            soundName: "default", // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played)
        });

// GROUP SUMMARY 
        PushNotification.localNotification({
            channelId: notification.channel_id,
            id: this.ids[notification.channel_id],
            group: notification.channel_id,
            subText: notification.subText,
            smallIcon: '@drawable/ic_stat_name',
            color: '#8000ff',
            groupSummary: true,
             title: notification.title, 
            message: notification.body,
            data: notification,

        })

Great!!!!!

You can use the PushNotification.getDeliveredNotifications too, to check if the curent group has any message delivered and decide if you should create an groupSummary or not, and avoid duplicate the notifications.

douglasdc avatar Sep 17 '20 21:09 douglasdc

@FranciscoCHT I have found a better solution without the need of extra channels. Using the following code you should not need an extra channel:

// POP UP NOTIFICATION
        PushNotification.localNotification({
            data: notification,
            showWhen: true, // (optional) default: true
            autoCancel: true, // (optional) default: true
            smallIcon: '@drawable/ic_stat_name', // (optional) default: "ic_notification" with fallback for "ic_launcher". Use "" for default small icon.
            subText: notification.subText, // (optional) default: none
            color: '#8000ff', // (optional) default: system default
            vibrate: true, // (optional) default: true
            vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000
            group: notification.channel_id, // (optional) add group to message
            ongoing: false, // (optional) set whether this is an "ongoing" notification
            priority: "high", // (optional) set notification priority, default: high
            visibility: "private", // (optional) set notification visibility, default: private
            importance: "high", // (optional) set notification importance, default: high
            allowWhileIdle: false, // (optional) set notification to work while on doze, default: false
            ignoreInForeground: false, // (optional) if true, the notification will not be visible when the app is in the foreground (useful for parity with how iOS notifications appear)
            channelId: notification.channel_id, // (optional) custom channelId, if the channel doesn't exist, it will be created with options passed above (importance, vibration, sound). Once the channel is created, the channel will not be update. Make sure your channelId is different if you change these options. If you have created a custom channel, it will apply options of the channel.
            onlyAlertOnce: false, //(optional) alert will open only once with sound and notify, default: false
            messageId,
            invokeApp: true, // (optional) This enable click on actions to bring back the application to foreground or stay in background, default: true
            alertAction: "view", // (optional) default: view
            category: "", // (optional) default: empty string
            title: notification.title, // (optional)
            message: notification.body, // (required)
            userInfo: {}, // (optional) default: {} (using null throws a JSON value '<null>' error)
            playSound: true, // (optional) default: true
            soundName: "default", // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played)
        });

// GROUP SUMMARY 
        PushNotification.localNotification({
            channelId: notification.channel_id,
            id: this.ids[notification.channel_id],
            group: notification.channel_id,
            subText: notification.subText,
            smallIcon: '@drawable/ic_stat_name',
            color: '#8000ff',
            groupSummary: true,
             title: notification.title, 
            message: notification.body,
            data: notification,

        })

Should i put those two methods in a single method? If i do i am receiving both the notifications, i need only one notification to be displayed

vimalswaroopj avatar Nov 27 '20 11:11 vimalswaroopj

@FranciscoCHT your solution works perfectly when app is in foreground. But how to achieve this in background/quit state?

saumaychainflux avatar Feb 05 '21 12:02 saumaychainflux

I'm bringing here simplified version because these from the top may confuse somebody at first (like it did to me)


// create one channel 

PushNotification.createChannel({
      channelId: 'messages',
      channelName: 'messages'
})

// use both in the same function (e.g. on socket.io event) ⬇️

// this shows each new notification for a while then pushes it into group

PushNotification.localNotification({
      channelId: 'messages',
      title: `New message from ${name}`,
      message: 'Hello GitHub',
}) 

// this groups messages

PushNotification.localNotification({
      channelId: 'messages',
      id: 'messages',
      group: 'messages',
      groupSummary: true
}) 

kuubson avatar May 15 '21 12:05 kuubson

I found many days and found an idea: From service only send data. All notification in ground have same id. First I send: "data": { "notification": { "title": "test title 2", "body": "Line 1", "bigText": "Line 1", "subText": "(1 message)", "id": 1 } } second I send: "data": { "notification": { "title": "test title 2", "body": "Line 2", "bigText": "Line 1 \nLine 2", "subText": "(2 message)", "id": 1 } } The second notification will override the first notification

daonamutc1 avatar May 20 '21 07:05 daonamutc1

For some reason, this solution is not working for me. Here is my code

PushNotification.createChannel({
                        channelId: "group_notifications",
                        channelName: "Group Notifications", 
                        channelDescription: "All activity notifications",
                        playSound: true, 
                        soundName: "default", 
                        vibrate: true,
                        importance: 2,
                    } );

And to show notifications

         PushNotification.localNotification({
                    channelId: "group_notifications",
                    title: notificationTitle || '',
                    message: notificationMessage || '',
                    data: data,
                    color: colors.primary,
                    smallIcon: 'ic_stat_notification',
                    largeIcon: 'ic_stat_notification',
                    id: this.msgId,  //Incremental value starting from 1
                    group: 'messages',
                    groupSummary: true,
           });

Can someone please tell me what i am doing it wrong here?

ajitdas123 avatar Feb 15 '22 13:02 ajitdas123

Any help on this ?

NJneeraj avatar Jan 10 '25 08:01 NJneeraj