Background
A lot of times in our app, we need to set up local push notifications. What do we mean by local notifications? Basically, the push notification does not trigger from cloud service, for example, a firebase push notification is a remote push notification service. Similarly, we have other push notification services for remote notifications.
However, sometimes we just want to set notifications from our app side. Let’s say we have a reminder system in our app and when the user sets a time we will need to set up a notification at that particular time.
We will see how we can achieve that in this blog post. We will be using a very good package called react-native-push-notification. In this post, I will be showing the android part, in the next post I will writing on iOS.
Demo Starts
Let’s start! First thing first, we need a demo app to show that our notifications are working. So, let’s create a demo app.
npx react-native init NotificationDemo
For the demo purpose, we need to have a DateTime input so that the user can set the notification time. For the DateTime picker, I am going to install react-native-date-picker. After installing this package, we will set up our demo component.
With the above, we get the following output.
Our demo app is all set up. Now let’s go to the main focus of this blog post – Notification. First, I am going to install the notification package.
yarn add react-native-push-notification
Don’t forget to pod install for iOS. We can basically follow the readme from the package, but since our main focus is local push notification we will ignore anything related to firebase setup from the documentation.
Android Setup
Just copy-paste this following portion in your AndroidManifest.xml
file inside <application>
, don’t forget to change the app name according to your app name where necessary.
<meta-data android:name="google_analytics_adid_collection_enabled" android:value="false" />
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name" android:value="NotifcationDemo"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description" android:value="NotifcationDemo Notifications"/>
<!-- Change the resource name to your App's accent color - or any other color you want -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@android:color/white"/>
<receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<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.RNPushNotificationListenerServiceGcm" android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
also, add the permission at the top.
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
One important setting to add, from the documentation – “If not using a built-in Android color (@android:color/{name}
) for the notification_color
meta-data
item. In android/app/src/main/res/values/colors.xml
(Create the file if it doesn’t exist).”
In my case for this demo app, I created the file inside android/app/src/main/res/values/colors.xml
and add the following inside this file.
<resources>
<color name="white">#FFF</color>
</resources>
With that our android native side’s setting is done! Now it is time to go back to our React Native App.
IOS SETUP
For our iOS setup, we need to first install @react-native-community/push-notification-ios. We can do that by yarn add @react-native-community/push-notification-ios
and then we need to run pod install
in our ios folder of the app. Now we need to follow few steps to make the iOS setup complete.
1. Add Capabilities : Background Mode – Remote Notifications
Go into your NotificationDemo/ios dir and open MyProject.xcworkspace workspace. Select the top project “NotificationDemo” and select the “Signing & Capabilities” tab. Add 2 new Capabilities using the “+” button:
Background Mode
capability and tickRemote Notifications
.Push Notifications
capability
2. Update AppDelegate.h
At the top of the file: #import <UserNotifications/UNUserNotificationCenter.h>
,
Then, add the ‘UNUserNotificationCenterDelegate’ to protocols: @interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
3. Update AppDelegate.m
At the top of the file:
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
Then, add the following lines:
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
}
And then in your AppDelegate implementation, add the following:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
// Define UNUserNotificationCenter
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
REACT NATIVE SETUP
In order to use react-native-push-notification, first we will create a Notifications
class that will hold the common configurations and services needed by the app. We can not initialize our Notifications inside a component, so it needs to be outside a component and should be at the root of our project.
I will be creating a Notifications class and export its instance directly from the file. In that way it will work as a singleton. Whenever we import the Notification class in any of our component it will be initialized one time and will be used throughout the whole app.
Let us see our Notifications class now –
Few breakdown of the above class
- We need to call configure first to initialize our PushNotification, note that we do not really need our onRegister func and onNotification func for this demo. But we do need to create the channel, without the channel the notifications won’t work
- Next we see the function called
scheduleNotification
which we will be using from our main app component. When user sets a date, we can also notice that it receives a date object.scheduleNotification
will schedule a local push notification for us at the datetime we pass to its’ option. We need to also mention channelD for it to work. A lot more customizations can be done. We are just setting a title and message for now.
That’s all! Now we just need to use this class in our main app component. We can do it when user presses the SET NOTIFICATION button.
Let’s see our final demo, Please note that for demo purpose I schedule my notification after 5 seconds.
Here is the git repo for this demo. That’s it for today, hopefully in my next blog post we will see this on iOS.