Local Push Notificatoin

2019-06-14

let's see how to implement Local Push Notification by using react-native-push-notification.

Outline

my applications what I’ve developed alone are downloaded more than before, but DAU(Daily Active User) is not changed big. so I try to implement Push Notification to increase DAU(Daily Active User). however I am a poor developer. so I can’t impelment Serverside Push Notification instead of Local Push Notification. the list below is my applications what I implement Local Push Notification.(sorry, it only supports Korean and Japanese) if you have any interested, please download it and see the demonstration.

in this blog post, we’ll see how to implement Local Push Notification by using react-native-push-notification library.

Install Library

execute the command below to install react-native-push-notification library.

npm install --save react-native-push-notification

execute the command below to link react-native-push-notification library to the App.

react-native link react-native-push-notification

as you can see the result of the command above, it only links on Android.

info Linking "react-native-push-notification" Android dependency
info Android module "react-native-push-notification" has been successfully linked

we should link by following the link below.

first, execute /ios/[project-name].xcworkspace or /ios/[project-name].xcodeproj to start xcode.

link react-native-push-notification library on iOS

drag node_modules/react-native/libraries/PushNotificationIOS/RCTPushNotification.xcodeproj to libraries on the botto of the project name in xcode. be careful. you should use react-native in node_moduels not react-native-push-notification.

next, click project name > Build Phases > Link Binary with Libraries.

link react-native-push-notification library - build phases

click + button on the bottom and search Push. select libRCTPushNotification.a in the search result and click Add to add it.

link react-native-push-notification library on iOS - add library in build phases

How To Use react-native-push-notification

the code below is what I use for my applications.

import { AppState, PushNotificationIOS } from 'react-native';
import PushNotification from 'react-native-push-notification';

const _handleAppStateChange = nextAppState => {
  if (nextAppState === 'active') {
    _registerLocalNotification();
  }
};

const _registerLocalNotification = () => {
  PushNotification.setApplicationIconBadgeNumber(0);
  PushNotification.cancelAllLocalNotifications();

  const messages = [
    '잠깐 시간내서 일본어 공부를 해보는건 어떨까요?',
    '오늘 일본어 공부하셨나요?',
    '일본어 단어를 공부해 보세요.',
    '단어 공부는 매일매일 하는 것이 중요해요.',
    '새로운 단어와 암기한 공부를 복습해 보세요.',
    '일본어를 공부할 시간이에요.',
    '테스트 기능을 사용해서 자신의 실력을 확인해 보세요.',
    '일본어 단어들이 당신을 기다리고 있어요.',
    '일본어, 어렵지 않아요. 공부해 봅시다.',
    '일본어 마스터가 되기위해!',
  ];
  const message = messages[Math.floor(Math.random() * messages.length)];

  let nextHour = new Date();
  nextHour.setDate(nextHour.getDate() + 1);
  nextHour.setHours(nextHour.getHours() - 1);


  PushNotification.localNotificationSchedule({
    /* Android Only Properties */
    vibrate: true,
    vibration: 300,
    priority: 'hight',
    visibility: 'public',
    importance: 'hight',

    /* iOS and Android properties */
    message, // (required)
    playSound: false,
    number: 1,
    actions: '["OK"]',

    // for production
    repeatType: 'day', // (optional) Repeating interval. Check 'Repeating Notifications' section for more info.
    date: nextHour,

    // test to trigger each miniute
    // repeatType: 'minute',
    // date: new Date(Date.now()),

    // test to trigger one time
    // date: new Date(Date.now() + 20 * 1000),
  });
};
export default {
  register: async () => {
    PushNotification.configure({
      onNotification: function(notification) {
        notification.finish(PushNotificationIOS.FetchResult.NoData);
      },
      popInitialNotification: true,
    });

    _registerLocalNotification();

    AppState.addEventListener('change', _handleAppStateChange);
  },
  unregister: () => {
    AppState.removeEventListener('change', _handleAppStateChange);
  },
};

let’s see more details.

import PushNotification from 'react-native-push-notification';
...
export default {
  register: () => {
    PushNotification.configure({
      onNotification: function(notification) {
        notification.finish(PushNotificationIOS.FetchResult.NoData);
      },
      popInitialNotification: true,
    });
    _registerLocalNotification();
    ...
  },
  ...
};

first, I’ve modularized this source code to use on many applications. when register() function is executed, PushNotification is initialized and then, call the function that registers Local Push Notification.

const _registerLocalNotification = () => {
  PushNotification.setApplicationIconBadgeNumber(0);
  PushNotification.cancelAllLocalNotifications();

  const messages = [
    ...
  ];
  const message = messages[Math.floor(Math.random() * messages.length)];

  let nextHour = new Date();
  nextHour.setDate(nextHour.getDate() + 1);
  nextHour.setHours(nextHour.getHours() - 1);


  PushNotification.localNotificationSchedule({
    /* Android Only Properties */
    vibrate: true,
    vibration: 300,
    priority: 'hight',
    visibility: 'public',
    importance: 'hight',

    /* iOS and Android properties */
    message, // (required)
    playSound: false,
    number: 1,
    actions: '["OK"]',

    // for production
    repeatType: 'day', // (optional) Repeating interval. Check 'Repeating Notifications' section for more info.
    date: nextHour,

    // test to trigger each miniute
    // repeatType: 'minute',
    // date: new Date(Date.now()),

    // test to trigger one time
    // date: new Date(Date.now() + 20 * 1000),
  });
};

when _registerLocalNotification is called to register Local Push Notification,

PushNotification.setApplicationIconBadgeNumber(0);
PushNotification.cancelAllLocalNotifications();

initialize Badge, and remove all Notifications registered before. why I cancel all Notifications, Local Push Notification is registered every times when the app is executed and that makes duplicate messages. I thought to use AsyncStorage to solve it, but I choose to delete all and register again.

...
const messages = [
...
];
const message = messages[Math.floor(Math.random() * messages.length)];

let nextHour = new Date();
nextHour.setDate(nextHour.getDate() + 1);
nextHour.setHours(nextHour.getHours() - 1);
...

the variables for making random message and for sending a message on tomorrow at one hour earlier than now.

PushNotification.localNotificationSchedule({
    /* Android Only Properties */
    vibrate: true,
    vibration: 300,
    priority: 'hight',
    visibility: 'public',
    importance: 'hight',

    /* iOS and Android properties */
    message, // (required)
    playSound: false,
    number: 1,
    actions: '["OK"]',

    // for production
    repeatType: 'day', // (optional) Repeating interval. Check 'Repeating Notifications' section for more info.
    date: nextHour,

    // test to trigger each miniute
    // repeatType: 'minute',
    // date: new Date(Date.now()),

    // test to trigger one time
    // date: new Date(Date.now() + 20 * 1000),
});

retister Local Push Notification. there are many options. you can see all options on the link below.

in my case, if my app is in Production,

repeatType: 'day', // (optional) Repeating interval. Check 'Repeating Notifications' section for more info.
date: nextHour,

show Local Push Notification at 1 hour earlier on every day. for the test,

// test to trigger one time
date: new Date(Date.now() + 20 * 1000),

trigger Local Push Notification one time after 20 seconds or,

// test to trigger each miniute
repeatType: 'minute',
date: new Date(Date.now()),

trigger at every minutes for testing.

import { AppState, PushNotificationIOS } from 'react-native';
...
const _handleAppStateChange = nextAppState => {
  if (nextAppState === 'active') {
    _registerLocalNotification();
  }
};
...
export default {
  register: async () => {
   ...
    AppState.addEventListener('change', _handleAppStateChange);
  },
  unregister: () => {
    AppState.removeEventListener('change', _handleAppStateChange);
  },
};

I check the app going to the background or in-activate by using AppState, and if the app is activated again, Local Push Notification is registered again. it’s for making random Local Push Notification message.

Apply To The App

we need to implement Local Push Notification module that we created above on the screen component that is always used when the app is executed like below.

...
import LocalNotification from '~/Util/LocalNotification';
...
export default class LevelScreen extends React.Component<Props, State> {
    ...
    componentWillUnmount() {
        LocalNotification.unregister();
        ...
    }
    componentDidMount() {
        LocalNotification.register();
        ...
    }
}

Android ic_launcher icon

you can see small icon on the left top of the Push Notification message on Android. I used generator-rn-toolbox to make this icon.

create 96x96 px size png file and check the file can be ic_launcher on the site below.

lastly, execute the command below to create iclauncher icon.

yo rn-toolbox:assets --android-notification-icon icon.png

if you want to know how to install generator-rn-toolbox and how to use it, see the previous blog posts.

Check

for checking, use the option below to register Local Push Notification in the app.

repeatType: 'minute',
date: new Date(Date.now()),

execute the app and make the app in-activate(exit or background). you can see Local Push Notification message like below after 1 minitue.

check Local Push Notification with react-native-push-notification

be careful. you should execute the app and make it in-activate to show the message.

Problem

when the app is executed, Local Push Notification is registered. in this time, the message is also registered, so if user doesn’t execute the app again to re-register Local Push Notification, the message will be always same.

I hope random messages are displayed, but if user doesn’t execute the app, maybe the same message makes user annoyed.

Completed

I think react-native-push-notification library is awesome. you can also control Serverside Push Notification with this library. if I become a rich developer, I will try to impelment Serverside Push Notification with react-native-push-notification library.

also, I will check Local Push Notification increases DAU(Daily Active User) or makes users annoyed and they delete the app.

Buy me a coffeeBuy me a coffee
Posts