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

Is there a way to send actions from server and show in remote notification in app and handle click on it?

Open v1pu2 opened this issue 5 years ago • 18 comments

v1pu2 avatar Sep 05 '20 13:09 v1pu2

Hi,

You can send data only notification, then pass data into the localNotification method. You will have to check for userInteraction to avoid loop.

Regards

Dallas62 avatar Sep 05 '20 21:09 Dallas62

My app is in background, and remote notification shows data, at that time how to pass data to localNotification method?

v1pu2 avatar Sep 07 '20 05:09 v1pu2

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

Dallas62 avatar Sep 07 '20 05:09 Dallas62

@Dallas62 Thanks for quick reply.

But, when my app is in background, onNotification didn't call.

I am using react-native-push-notification version 5.1.0. My notification data came from server. There I have used fcm-notification. I have configure notification for Android only.

Below are my files in front app, where I have put notification code. Please help me to navigate on specific screen when remote notification fired(app should be in background) and also show action buttons in notification tray which handle few activity.

Authloading screen

class AuthLoading extends React.Component {
  constructor() {
    super();
    this.state = {};
  }
  componentDidMount() {
    configurePushNotification(this.props.navigation);
  }
  render() {
    return (
      <View style={styles.container}>
      </View>
    );
  }
}

configurePhushnotification screen

import { storeData } from "../src/helpers/asyncStorage";

let PushNotification = require("react-native-push-notification");
let storage = {};
PushNotification.configure({
  onRegister(token) {
    // console.log("token in onRegister configure", token);
    storage.token = token;
    storeData("notification_token", token.token).then((val) => {
      // stored token to asyncstorage
    });
  },

  // (required) Called when a remote or local notification is opened or received
  onNotification(notification) {
    console.log("notification is", notification);
    if (!notification.userInteraction) {
      console.log("inside not userInteraction", notification.data);
      PushNotification.localNotification(notification.data);
    }

    if (notification.userInteraction) {
      console.log("in use interaction", notification.data);
      PushNotification.localNotification(notification.data);
    }
  },

  senderID: "Sender_id",
  permissions: {
    alert: true,
    badge: true,
    sound: true,
  },

  popInitialNotification: true,
  requestPermissions: true,
});

export default function configurePushNotification(navigation) {
  // console.log('in configure token from storage', storage.token);

  PushNotification.localNotification = (notif) => {
    console.log("in localnoti", notif);
    navigation.navigate(notif.path);
  };
  return null;
}

Here is my manifest file.

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme"
     >
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
         android:screenOrientation="portrait"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

      <!--notifications setup-->
      <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name"
                android:value="CHANNEL_NAME"/>
      <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description"
                  android:value="CHANNEL_DESC"/>
      <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@mipmap/ic_launcher_round" />

      <meta-data  android:name="com.dieam.reactnativepushnotification.notification_foreground"
                    android:value="true"/>

       <meta-data  android:name="com.dieam.reactnativepushnotification.channel_create_default"
                    android:value="false"/>

      <meta-data  android:name="com.dieam.reactnativepushnotification.notification_color"
                  android:resource="@android:color/white"/>
                  
      <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
      <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />

      <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
          <intent-filter>
              <action android:name="android.intent.action.BOOT_COMPLETED" />
          </intent-filter>
      </receiver>

      <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/>

      <service
          android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
          android:exported="false" >
          <intent-filter>
              <action android:name="com.google.firebase.MESSAGING_EVENT" />
          </intent-filter>
      </service>
       </application>

v1pu2 avatar Sep 10 '20 06:09 v1pu2

Hi @v1pu2 What do you send from the server? What's the payload ?

Dallas62 avatar Sep 10 '20 07:09 Dallas62

My notification payload looks like

 let message = {
    data: data,
    notification: {
      title: title,
      body: body
    }
  }
 FCM.sendToMultipleToken(message, tokens, function(err, response) {
    if (err) {
      console.log('err--', err)
    } else {
      console.log('response-----', response)
    }
  })

v1pu2 avatar Sep 10 '20 07:09 v1pu2

Hi, In the solution I suggested, you must send data-only notification. In your payload you send notification+data, which lead to not triggering onNotification. Use the same parameters as in localNotification(params) in your notification data.

Dallas62 avatar Sep 10 '20 07:09 Dallas62

Hi, I have removed data from payload from server side.

 let message = {
    notification: {
      title: title,
      body: body,
      // sound: 'store_door_chime_mike_koenig_570742973.wav'
    }
  }

My notification response like

 {"color": null, "data": {}, "finish": [Function finish], "foreground": true, "id": "831697751", "message": "Your order is ready. Kindly collect it from the cafeteria.", "sound": null, "title": "It's Smokin' Hot!", "userInteraction": false}

But onNotification didn't call.

For custom sound, I have sent from server like above code but did't get notification. I have also tried with only file name(without extension), but didn't work.

v1pu2 avatar Sep 10 '20 12:09 v1pu2

using https://www.npmjs.com/package/fcm-notification from backend to send remote notification.

v1pu2 avatar Sep 10 '20 12:09 v1pu2

You must send DATA-only notification, not a notification-only or a notification with data.

https://firebase.google.com/docs/cloud-messaging/android/receive#handling_messages

App state Notification Data Both
Foreground onMessageReceived onMessageReceived onMessageReceived
Background System tray onMessageReceived Notification: system trayData: in extras of the intent.

Such as:

 let message = {
    data: {
      title: title,
      message: body,
      ...data
    }
  }
 FCM.sendToMultipleToken(message, tokens, function(err, response) {
    if (err) {
      console.log('err--', err)
    } else {
      console.log('response-----', response)
    }
  })

Dallas62 avatar Sep 10 '20 12:09 Dallas62

Hi @v1pu2! Is it ok for you ?

Dallas62 avatar Sep 12 '20 20:09 Dallas62

hello @Dallas62 i found that data only messages are sometimes not recieved or delayed can you please comment

Yashpk789987 avatar Dec 09 '20 23:12 Yashpk789987

Hi @Yashpk789987 I'm not responsable of APNS or Firebase, please check official documentation or StackOverflow for potential delay. Regards,

Dallas62 avatar Dec 09 '20 23:12 Dallas62

Hi @Dallas62, I was also getting the same issue. So, I changed the notification to data only. Now, I can see the local notification when app is in foreground or backgroud but couldn't see the notification when the app is inactive(killed state). 'onNotiifcation' method is not getting called in killed state. Will you plz help on this? Thanks!

Aexonic-Abhishek avatar Sep 20 '21 10:09 Aexonic-Abhishek

Hi, Something is intercepting the notification, Check the example project and do not put .configure() inside a component. Regards

Dallas62 avatar Sep 20 '21 11:09 Dallas62

Thanks @Dallas62 , will try to figure it out

Aexonic-Abhishek avatar Sep 20 '21 11:09 Aexonic-Abhishek

@Dallas62 solved the issue on Android but now, I'm not able to see notifications on iOS after changing the notification object to data only. However, as soon as I get the notification on iOS, I can see the incremented badge number on the icon. Is there anything that I'm doing wrong?

Library versions: "@react-native-community/push-notification-ios": "^1.8.0", "react-native-push-notification": "^7.2.3", "react": "17.0.1", "react-native": "0.64.0"

Code:

onNotification: function (notification) { Alert.alert(JSON.stringify(notification)) if(!notification.userInteraction) { PushNotification.localNotification({ soundName:'sampleaudio.wav', channelId:'fcm_FirebaseNotifiction_default_channel', title: notification.data.title, message: notification.data.message, autoCancel: true, priority: "high", userInfo: notification.data, actions: ["Cancel", "Complete"], category: 'userAction', }) }else { if(notification.action == 'Cancel' || notification.action == 'Complete') { PermissionService.onNotificationActionPress(notification); }else { PermissionService.onClickPushNotification(notification.data); } } notification.finish(PushNotificationIOS.FetchResult.NoData); },

Thanks!

Aexonic-Abhishek avatar Sep 21 '21 04:09 Aexonic-Abhishek

@Aexonic-Abhishek hey how did u handle the click actions cuz this doesn't work, i click on the action and nothing happens

if(notification.action == 'Cancel' || notification.action == 'Complete') {
    PermissionService.onNotificationActionPress(notification);
} else {
    PermissionService.onClickPushNotification(notification.data);
}

Thanks

riad40 avatar Sep 17 '24 16:09 riad40