zo0r / react-native-push-notification

React Native Local and Remote Notifications
MIT License
6.73k stars 2.05k forks source link

Cannot send to notification centre because there is no 'message' field in: Bundle #1452

Closed rohitkum28 closed 3 years ago

rohitkum28 commented 4 years ago

I am trying to include version 3.5.0 of the library in my current react-native project. Earlier in one of my older project I was using version 3.1.9 of the library. From my server when I try to POST something like

{
"to" : "MY_FCM_TOKEN",
"data" : {
    "message" : "Some Test Message",
    "title": "Test Title",
    "route" : "Home"
}
}

It shows up in as a notification in my old project but it doesn't show up as notification with the latest version of the library. On debugging the issue further and checking my adb logs, I see the following error.

D/RNPushNotification: Cannot send to notification centre because there is no 'message' field in: Bundle[{userInteraction=false, id=844951609, data=Bundle[{route=Home, title=Test Title, message=Some Test Message}], foreground=true}]

This is not the case with version 3.1.9 of the library.

Environment Info

"react": "16.9.0",
"react-native": "0.61.5",
"react-native-push-notification": "^3.5.0"
Dallas62 commented 4 years ago

Hi @rohitkum28 Can you show us the method onNotification ? Note that a breaking change has not been caught in time, now data are now in notification.data instead of notification. https://github.com/zo0r/react-native-push-notification/pull/1212

rohitkum28 commented 4 years ago

Hi @Dallas62

1212 explains the issue I am facing. But, this change has broken notification in other libraries which sends push notification. For example, I am using Comet Chat in my application which uses Firebase to send push notification for chat. And with the latest version react-native-push-notification, it is not working now. Even if I handle the foreground state by generating a local notification when I receive the payload, the background state is still a problem.

Is downgrading the version of the library the only option? Or is there any other workaround for it?

Dallas62 commented 4 years ago

I'm not sure to understand the problem with Comet Chat. I don't see any notification library in the link you provided ? Can you share some code on how it's working with onNotification ?

rohitkum28 commented 4 years ago

Here is my code for Component to handle Push notification

import { useEffect } from 'react'
import PushNotification from 'react-native-push-notification'
import { Platform } from 'react-native'

const onOpenNotification = (notify) => {
    console.log("[Notification] onOpenNotification :", notify);
    //alert("onOpenNotification " + notify.title)

}

const RemotePushController = () => {
    useEffect(() => {
        PushNotification.configure({
            // (optional) Called when Token is generated (iOS and Android)
            onRegister: function (token) {
                console.log('TOKEN:', token)
            },
            // (required) Called when a remote or local notification is opened or received
            onNotification: function (notification) {
                console.log('REMOTE NOTIFICATION ==>', JSON.stringify(notification))
                // process the notification here
                if (notification.userInteraction) {
                    onOpenNotification(notification)
                }
                if (Platform.OS === 'android') {
                    notification.userInteraction = true
                }

            },
            popInitialNotification: true,
            // Android only: GCM or FCM Sender ID
            senderID: 'FCM_SENDER_ID',
            requestPermissions: true
        })
    }, [])
    return null
}
export default RemotePushController

And I using this component inside my App.js. This same code works with version 3.1.9 of the library with the above push notification json I shared. But, with version 3.5.0, I see the above error message in adb console. The question I have is if there is any way to make it work with version 3.5.0?

Dallas62 commented 4 years ago

The problem is a side effect of moving data from notification to notification.data. In fact data and notification were merged and overrided in some cases. To fix this, change the payload send by the server to:

{
"to" : "MY_FCM_TOKEN",
"notification" : {
    "body" : "Some Test Message",
    "title": "Test Title"
},
"data": {
    "route" : "Home"
}
}

Note:

rohitkum28 commented 4 years ago

@Dallas62 ,

Since we don't have the control over the server that sends the payload, is downgrading the library only option left now?

Dallas62 commented 4 years ago

There is another option, you can trigger a local notification when you receive data from server. If there is extra data you will have to store them since local notification doesn’t store data.

eporomaa commented 4 years ago

@Dallas62

The problem is a side effect of moving data from notification to notification.data. In fact data and notification were merged and overrided in some cases.

Could you please elaborate on this, where was the move from notification to notfication.data performed?


I got the same issue: D/RNPushNotification: Cannot send to notification centre because there is no 'message' field in: Bundle[... when sending notifications to an Android device via FCM through AWS PinPoint using their JS SDK. This was using their "standarized" format which I expected would format the request properly to FCM, appears not.

My resolution was to use the RawContent field of the GCMMessage and then send a request on the by @Dallas62 above-mentioned format. Thx!

sstimac commented 4 years ago

I ended up with a temporary solution of patch-packaging the latest version with the following change. I simply included all of the keys in the bundle, like the lib used to work, but retained the latest code as well. It's not a clean solution as it possibly duplicates things, but it works for my case.

diff --git a/node_modules/react-native-push-notification/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNReceivedMessageHandler.java b/node_modules/react-native-push-notification/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNReceivedMessageHandler.java
index 04038bc..a10a8ab 100644
--- a/node_modules/react-native-push-notification/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNReceivedMessageHandler.java
+++ b/node_modules/react-native-push-notification/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNReceivedMessageHandler.java
@@ -50,6 +50,10 @@ public class RNReceivedMessageHandler {
             bundle.putString("color", remoteNotification.getColor());
         }

+        for(Map.Entry<String, String> entry : message.getData().entrySet()) {
+            bundle.putString(entry.getKey(), entry.getValue());
+        }
+
         Map<String, String> notificationData = message.getData();

         // Copy `twi_body` to `message` to support Twilio
tmaly1980 commented 4 years ago

I try calling PushNotification.localNotification() after receiving a remote notification, and I STILL get another "Cannot send to notification centre" error for the local notification. How do I fix this? What version did this break? I'm at the point where I'm seriously considering switching over to using FCM directly via react-native-firebase.

Dallas62 commented 4 years ago

I try calling PushNotification.localNotification() after receiving a remote notification, and I STILL get another "Cannot send to notification centre" error for the local notification. How do I fix this? What version did this break? I'm at the point where I'm seriously considering switching over to using FCM directly via react-native-firebase.

Hi @tmaly1980 Can you provide a reproducible example?

bneigher commented 4 years ago

@Dallas62 it looks like react-native-intercom is another example of a 3rd party service that is not compatible with react-native-push-notification after the last few updates.

D/RNPushNotification: Cannot send to notification centre because there is no 'message' field in: Bundle[{userInteraction=false, id=-1707122002, data=Bundle[{app_id=<>, image_url=https://static.intercomassets.com/avatars/...., receiver=intercom_sdk, avatar_color=#7C68F1, conversation_id=..., intercom_push_type=notification, body=Ben: hi, author_name=Ben, message=Ben: hi, app_name=MY_APP, conversation_part_type=comment}], foreground=false}]

Since there is a free tier, perhaps that would suffice as a repro example?

The last version that was working with this (and I have the same problem with aws pinpoint) was 3.1.9

Dallas62 commented 4 years ago

Hi @bneigher I will not spend time on implementing a reproducible example of this issue since there is many possible reasons of bugs such as different configuration. If you are able to implement this issue with the example folder of this repo, I would be pleased to help you.

bneigher commented 4 years ago

@Dallas62 understood and frankly I wouldn't either if I were you lol.

At least take a look at this - intercom's README specifically calls out to a change that FCM clients must do:

https://github.com/tinycreative/react-native-intercom#heres-an-example-if-youre-using-react-native-firebase-as-your-existing-fcm-setup

If it looks like we can substitute your library so we don't have to install react-native-firebase to accomplish this that will probably suffice for most people. Otherwise if by looking at this you see a way to adapt the source to include this payload change that would be cool too

Dallas62 commented 4 years ago

Hi @bneigher

Can you share you AndroidManifest ? (Remove secrets and hide name if you prefer)

This will help if I found time on this issue. Regards

MaganAnkur commented 3 years ago

@Dallas62 ,

Since we don't have the control over the server that sends the payload, is downgrading the library only option left now?

@rohitkum28 I am facing the same issue, by any chance were you able to fix it"

Dallas62 commented 3 years ago

Hi @MaganAnkur You don't have the control over the notification payload, ok. But you have the control of the application? Can't you just pass the data to localNotification method ?

onNotification: function(notification) {
if(!notification.userInteraction) {
PushNotifications.localNotification(notification.data);
}
}

This is an example from my phone, fix syntax if needed. Also check the content of data to fit the localNotification parameters.

rohitkum28 commented 3 years ago

@Dallas62 , Since we don't have the control over the server that sends the payload, is downgrading the library only option left now?

@rohitkum28 I am facing the same issue, by any chance were you able to fix it"

As a temporary solution, I downgraded the version of the library to 3.1.9. But after that, I shifted to react-native-firebase. And as @Dallas62 mentioned, we will need to call PushNotifications.localNotification() when notification in payload is null and only data payload is present.

avlonder commented 3 years ago

Any updates on this? The proposed workaround with LocalNotification is not working

gevgasparyan commented 3 years ago

The problem is a side effect of moving data from notification to notification.data. In fact data and notification were merged and overrided in some cases. To fix this, change the payload send by the server to:

{
"to" : "MY_FCM_TOKEN",
"notification" : {
  "body" : "Some Test Message",
  "title": "Test Title"
},
"data": {
  "route" : "Home"
}
}

Note:

Thanks, it works!

Sylchauf commented 3 years ago

This workaround works for me :

onNotification: function (notification) {
    if (notification.userInteraction === false)
         PushNotification.localNotification(notification.data);
}

Used with Sendbird service (but works for Intercom too i think)

EDIT : thanks to @Dallas62 advice

Dallas62 commented 3 years ago

This workaround works for me :


onNotification: function (notification) {

    PushNotification.localNotification(notification.data);

}

Used with Sendbird service (but works for Intercom too i think)

Hi @Sylchauf

This code is working, but take care of notification.userInteraction === false when you trigger the localNotification. That avoid infinite loop when the user press the notification.

Regards,

nicholascm commented 3 years ago

@Dallas62

The problem is a side effect of moving data from notification to notification.data. In fact data and notification were merged and overrided in some cases.

Could you please elaborate on this, where was the move from notification to notfication.data performed?

I got the same issue: D/RNPushNotification: Cannot send to notification centre because there is no 'message' field in: Bundle[... when sending notifications to an Android device via FCM through AWS PinPoint using their JS SDK. This was using their "standarized" format which I expected would format the request properly to FCM, appears not.

My resolution was to use the RawContent field of the GCMMessage and then send a request on the by @Dallas62 above-mentioned format. Thx!

Do you happen to have an example of that full payload which is working for you? I am still having this issue sending via AWS SNS.

Dallas62 commented 3 years ago

Hi @nicholascm As mentioned many times in this topic:

onNotification: function (notification) {
    if (!notification.userInteraction) {
         PushNotification.localNotification(notification.data);
    }
}

Where data is the content of: https://github.com/zo0r/react-native-push-notification#local-notifications

Regards,

nicholascm commented 3 years ago

Hi @nicholascm As mentioned many times in this topic:

onNotification: function (notification) {
    if (!notification.userInteraction) {
         PushNotification.localNotification(notification.data);
    }
}

Where data is the content of: https://github.com/zo0r/react-native-push-notification#local-notifications

Regards,

I think my issue maybe around what the person I quoted mentioned, where AWS SNS does not send the properly formatted message as I am also using AWS SNS. Even if I send messages formatted with the required fields as you mentioned, I have the there is no 'message' field in: Bundle[... error.

Ignore this message if you sent data-only notification. Cannot send to notification centre because there is no 'message' field in: Bundle[{userInteraction=false, id=938808074, data=Bundle[{default={
03-17 10:44:57.845 29125 29125 D RNPushNotification:     "message": "some message",
03-17 10:44:57.845 29125 29125 D RNPushNotification:     "channelId": "default-channel-id",
03-17 10:44:57.845 29125 29125 D RNPushNotification:     "notification": {
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "message": "some message",
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "body": "Some Test Message",
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "title": "Test Title"
03-17 10:44:57.845 29125 29125 D RNPushNotification:     },
03-17 10:44:57.845 29125 29125 D RNPushNotification:     "data": {
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "route": "Home",
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "channelId": "default-channel-id",
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "showWhen": true,
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "autoCancel": true,
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "largeIcon": "ic_launcher",
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "largeIconUrl": "https://www.example.tld/picture.jpg",
03-17 10:44:57.845 29125 29125 D RNPushNotification:         "message": "My Notification Message"
03-17 10:44:57.845 29125 29125 D RNPushNotification:     }
03-17 10:44:57.845 29125 29125 D RNPushNotification: }}], foreground=false}]
Dallas62 commented 3 years ago

So you must adapt the SNS format to the right format (firebase one or to fit localNotification parameters).

nicholascm commented 3 years ago

I was able to get the remote notification sent by AWS SNS to show by doing the below:

PushNotification.configure({
   ...config,
  onNotification: function(notification) {
    let message = notification?.data?.default; // this seems weird to me. My data is always a string - I can Parse the JSON if it is JSON here or send only a string and display (as shown below)
    if (!notification.userInteraction) {
      PushNotification.presentLocalNotification({
        message: message || 'New notification',
        channelId: 'default-channel-id',
      });
    }
  },
  senderID: 'some-id',
  popInitialNotification: true,
  requestPermissions: true,
});
olegmilan commented 3 years ago

I was able to get the remote notification sent by Mattermost Push Proxy using workaround provided by @nicholascm

val3ntin-ch commented 2 years ago

Hi @Dallas62 i have the same issue for silent push notification, i got the PN when the app it's running or it is in background but not getting any PN when the app it's killed, i tried all the solution mention above but nothing it's working, when i add the body key to PN it hits the app and PN it's shown, but it s not the intended functionality as i want to show a local PN after i process the data from PN: My PN object it s as fallows: { foreground: true finish: ƒ finish() userInteraction: true id: "-1555648569" data: { "key-value": "value"} },

In Android Studio i see that onMessageReceived: has the PN, sendNotification: has the same PN, but i still get RNPushNotification: Ignore this message if you sent data-only notification. Cannot send to notification centre because there is no 'message' field in: Bundle etc. Does silent PN are intended only to be used when the app it s in background or running?

Dallas62 commented 2 years ago

Please check the example project and Readme, your configuration must be wrong.

val3ntin-ch commented 2 years ago

Hi @Dallas62 , thank for hint , as a POC i created a new project from 0.

when i sent this payload from postman { "to":"my-token", "notification" : { "body" : "New announcement assigned", "OrganizationId":"2", "content_available" : true, "priority" : "high", "subtitle":"Elementary School", "Title":"hello", "fourground": false }, "data" : { "body" : "My TExt", "priority" : "high", "sound":"app_sound.wav", "content_available" : true, "bodyText" : "New Announcement assigned", "organization" :"Elementary school" } }

i get PN when the app it s killed (in STATUS BAR from where i can open the app and show a local notification where i can do my localization( the issue it s that in status bar i have a message that it s not localized)

when i send this paylaod - to show a local notification with localized data { "to":"my_token", "time_to_live": 86400, "collapse_key": "new_message", "delay_while_idle": false, "data" : { "body" : "My TExt", "priority" : "high", "sound":"app_sound.wav", "content_available" : true, "bodyText" : "New Announcement assigned", "organization" :"Elementary school" } } i get the PN but not in status bar from where i can open the app and show notif etc....

Screenshot 2021-07-23 at 17 16 23

did i missed something as i already tried all that it is in readme and the example model and i still have the same issue, Thank you

Dallas62 commented 2 years ago

Please fix your markdown.

Then re-read the readme Usage, especially this first bold line.

Regards

val3ntin-ch commented 2 years ago

Please fix your markdown.

Then re-read the readme Usage, especially this first bold line.

Regards

Fixed it