question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

README: Local Notification Tutorial, How To, Notes, Usage (not relevant to remote/push notifications)

See original GitHub issue

I understand this is not technically an issue, but the amount of hours I’ve spent crawling over all the posts in this repo, I wanted to give back and potentially help some other people out. I didn’t want this to be lost in the sea of unmerged PRs. Any and all feedback would be greatly appreciated. I’m hoping to catch the attention of a contributor so we can get this merged into official docs!!

version notes:

"react-native": "0.51.0",
"react-native-push-notification": "3.0.2",
"react-native-navigation": "1.1.323",
"react-redux": "5.0.6",
"redux": "3.7.2",

Initial set up and installation

  • on android, it is not necessary, in fact it may break your app, to use
compile ('com.google.android.gms:play-services-gcm:8.1.0') {
        force = true;
    }

in the dependencies section of your android/app/build.gradle

local notifications will run fine without it. I do not have push notifications set up, but I image it is quite necessary for push(remote) notifications

  • if you are installing for the first time or have been struggling to get this to work. My advice is to skip the react-native link react-native-push-notification step in the instructions and manually link everything yourself. Don’t forget to edit the header search path in your xcode project as well so the #import <React/RCTPushNotificationManager.h> will be able to find the correct file. This is step 3 in the facebook react native docs.

Here is how I got my local notifications to work. My project doesn’t use push notifications. I use moment instead of the javascript date, but use moment().toDate() as per the momentjs docs to get the javascript object to pass back into this library.

this example only schedules a local notification for 3 seconds after it was initially created

Some notes

when adding id to the notification so that you can potentially cancel it later.

  • In android, the id is added to the root level of the notification object, meaning the same level in the object in which the message and date are. That id has to not only be of type String, but it has to ALSO be a stringified number.

  • In ios, the id must go into the userInfo object. The value of id must also be of type String, but does not necessarily have to be a stringified number (I haven’t tested that case). However, most likely if you are developing for both ios and android, it would be better practice to keep ids the same across platforms.

To solve this issue, I created a constants file that mapped a string such as 'someNotificationId' to a stringified number such as '111' to keep cross-platform notifications consistent, and I used a helper function to perform that mapping for me. I will include the constant and helper function down below as well. This allows you to develop with a text string for the id that you pass into a helper function which turns it into a predetermined stringified number that you can black box away once you set up that mapping.

receiving notifications

  • On android, the user will the receive local notifications alert (the one the comes down from the top of the phone) whether the app is in the foreground or background, however, the onNotification function will not fire until the notification is tapped. Then onNotification is fired and you can do what you want with the payload. onNotification is not fired on receipt of the notification, regardless of whether the app is in the foreground or background. From what I’ve read in these docs and android docs, this is intended behavior.

  • On ios, the user will only receive the local notification alert if the app is in the background. It will not show up if the app is foregrounded. The difference between ios and android is in the onNotification callback. On ios, if the app is in the foreground and it receives a notification, onNotification will be fired and you can do something with the payload. I opted to show it as a toast within the app, so the notification still gets delivered. onNotification will still be fired if the app is in the foreground and the user taps on a delivered notification. onNotification will not be called if the app is in the background and the notification has been delivered but has not been interacted with by the user.

passing a payload with the notification

  • On android, there are 2 requirements. The first is that you must JSON.stringify(payload) the payload. I have only used objects as the payload, so I am unsure as to if other types of payloads are supported. The second is that to attach it the notification, you must add it to the data key in the root level of the notification object, on the same level as the ‘id’ key as shown in the example above.

  • On ios, the payload does not need to be stringified and can be added to the userInfo object. I opted to explicitly specify the id property in userInfo and spread the payload object. For those unsure about the spread operator usage. Here is a quick example:

const obj1 = {fruit: 'apple'};
const obj2 = {veggie: 'broccoli'};

const obj3 = {...obj1, ...obj2};
console.log(obj3);  // will show {fruit: 'apple', veggie: 'broccoli'}

console.log({
  meat: 'chicken',
  ...obj3,
}; // will show {meat: 'chicken', fruit: 'apple', veggie: 'broccoli'}

Both on ios and android the payload will show up under the data key inside the notification object returned by onNotification. You can then process the payload however you like.

cancelling notifications

  • simply call cancelLocalNotifications({id: yourNotificationId}). The only gotcha is that on iOS you need to specify another property on the notification object called number and set it to an integer value (I chose 0 arbitrarily). I do not know what is does at this time or why it works, only that if you don’t have the number property on the notification object, you cannot cancel the notification.

scheduling notifcations

  • on both ios and android, the date property must be a Javascript Date object. You can convert a moment to a Date object using the moment().toDate() function

constructing the notification object

this refers to the notification object before dispatching it with PushNotification.localNotificationSchedule(notification)

  • I have found the you don’t need to fork the code for Platform specific things like userInfo (is only on ios) and data is used by android. You can construct it to be platform agnostic and the appropriate OS will take the properties that it needs and can use.

note about the code below

I have wrapped this libraries functions with my own to make the API more reusable for my needs, you may find that it works for you, otherwise adjust it to your liking. But the construction of the notification object and the dispatching of the notification should all be exceedingly similar

export function scheduleLocalNotification(message, date, id, payload) {
  //message: type String
  //date: type String  format 'YYYY-MM-DD HH:mm' (NOTIFICATION_DATE_TIME_FORMAT)

  //construct the notification parameters
  // const fireDate = moment(date, NOTIFICATION_DATE_TIME_FORMAT).toDate();
  const fireDate = moment()
    .add(3, 'seconds')
    .toDate();
  const notification = {
    id: createPushId(id), //for android cancel notification (must be stringified number)
    message,
    number: 0, //necessary for iOS cancellation (not sure why)
    date: fireDate,
    //for ios only
    userInfo: {
      id: createPushId(id), //for ios cancel notfication (can be any string)
      ...payload,
    },
    //for android only
    data: JSON.stringify(payload),
  };

  //schedule the notification
  PushNotification.localNotificationSchedule(notification);
}

export function createPushId(pushType) {
  return NOTIFICATION_TYPE_TO_ID[pushType];
}

export const NOTIFICATION_TYPE_TO_ID = {
  fruit: '111',
  meat: '222',
  veggies: '333',
};

so i can now call anywhere inside my RN app

scheduleLocalNotification(
  'This is a test message',
  '2018-03-24 15:45',
  'fruit',
  {foo: 'bar'}
)

and it will be dispatched as a notification that will fire at 3:45PM on march 24, 2018. It will have the id of 'fruit' or technically '111' because of the mapping and the payload is {foo: 'bar'}. you can cancel it by calling PushNotification.cancelLocalNotifications({id: createPushId('fruit')})

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:46
  • Comments:15 (1 by maintainers)

github_iconTop GitHub Comments

5reactions
Gp2mv3commented, Jul 8, 2018

This should be added in a doc or readme file in the repo !

1reaction
wmoneckecommented, Feb 19, 2018

Damn this is very useful! Is there any way to make android behave like iOS in the sense that you only get local push notifications if the app is in the background?

Read more comments on GitHub >

github_iconTop Results From Across the Web

React Native Local Push Notifications | by Saad Khan - Medium
I will suggest to use Notifee library at this point to do your local and remote push notifications. It is so good and...
Read more >
Push Notifications and Local Notifications - Tutorial
By using notifications, you can notify the user about important events even when the app is not running. In this tutorial you will...
Read more >
Local and Remote Notification Programming Guide
Describes how apps can send and receive user notifications locally and remotely.
Read more >
awesome_notifications | Flutter Package - Pub.dev
Notifications could be created at any moment (on Foreground, Background or even when the application is terminated/killed). High trustworthy on receive ...
Read more >
How to Create Web Push Notifications - Full Tutorial
The push API allows web apps to receive messages from a server, even when the website is not open. We can use this...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found