React Native Reminders with Firebase integration

sudhirkumar
7 min readNov 25, 2019

React Native Firebase Integration:

React Native Firebase is the best way to send messages and notifications to Users across platforms — Android, iOS, and the web — for free. Messages can be sent to single devices, groups of devices, or specific topics or User segments. Firebase Cloud Messaging (FCM) scales to even the largest apps, delivering hundreds of billions of messages per day.

React native firebase Plugin

Use a simple command to integrate the Firebase to your app.

yarn add react-native-firebase

After installing the firebase, go to Google Console.

Create a fresh project with same name as your project by clicking on the Add project button. Once you have completed the whole setup. Now its time to integrate and create app-specific

iOS Installation: Core Setup

  1. Go to Project Dashboard and click on the Add app button at the top. Once you have clicked on the button a new window would open to register firebase credentials depending on your platform. Choose iOS, for now, later on, we would use the same button to create Android credentials as well.
  2. Google Service Infoplist is a file having all the credentials. Enter the name of your app like com.james.notifications. Rest two values are optional and you can skip that. Once done download the file and store it in the app folder of XCode of your project.
  1. Update AppDelegate.m file: To initialize the native SDK in your app, add the following to your ios/[YOUR APP NAME]/AppDelegate.m file
#import <Firebase.h>@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure]; // Add this line to the existing code.

2. Update podFile: You can go to the iOS folder of your project and look for PodFile. Add the following line before the target code of testing.

# Required by RNFirebase
pod 'Firebase/Core', '~> 6.6.0'
Run pod install once you have updated the code.

3. The last step is to link the module with the project. You need to run the code once

// Add this code to your podfilepod 'RNFirebase', :path => '../node_modules/react-native-firebase/ios'// Once pod is updated link the plugin with the following commandreact-native link react-native-firebase

Once this is done we are done with React native linking for iOS. Let’s learn more about Android.

Android Installation: Core Setup

  1. Repeat the iOS installation step 1 but this time for android and register the app to download it later. Once downloaded, place this file in the root of your project at android/app/google-services.json.
  2. In your main build.gradle file of the android folder, you need to add the following lines.
buildscript {
// ...
dependencies {
// ...
classpath 'com.google.gms:google-services:4.2.0'
}
}
// To apply the plugin to your project, add the following to the VERY BOTTOM of your app android/app/build.gradle file:apply plugin: 'com.google.gms.google-services'

3. In the android/app/build.gradle file, add the following:

dependencies {
// This should be here already
implementation project(':react-native-firebase')
// Firebase dependencies
implementation "com.google.android.gms:play-services-base:16.1.0"
implementation "com.google.firebase:firebase-core:16.0.9"
...

You have successfully integrated the library with both iOS and Android Platforms.

Notification Module Setup

As we are going to add notification. We would need two basic modules of firebase for notifications that are Cloud messaging and Notifications.

iOS installation:Notifications

Add the following code to your existing podfile.

pod 'Firebase/Messaging'
pod update

Add the following import to the top of your ios/[App Name]/AppDelegate.m:

#import "RNFirebaseNotifications.h"

Add the following to the didFinishLaunchingWithOptions:(NSDictionary *)launchOptions the method, right after [FIRApp Configure]:

[RNFirebaseNotifications configure];

Add the following method:

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}

Remote Notifications (Optional)

If you would like to support Remote Notifications via FCM, also add the following import to the top of your ios/[App Name]/AppDelegate.m:

#import "RNFirebaseMessaging.h"

Then add the following methods to your ios/[App Name]/AppDelegate.m:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}

Android installation: Notifications

Add the Firebase Cloud Messaging dependency and optional ShortcutBadger dependency to android/app/build.gradle:

dependencies {
// ...
implementation "com.google.firebase:firebase-messaging:15.0.2"
implementation 'me.leolin:ShortcutBadger:1.1.21@aar' // <-- Add this line if you wish to use badge on Android
}

Install the RNFirebase Messaging package

Add the RNFirebaseMessagingPackage to your android/app/src/main/java/com/[app name]/MainApplication.java:

// ...
import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage; // <-- Add this line
public class MainApplication extends Application implements ReactApplication {
// ...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNFirebasePackage(),
new RNFirebaseMessagingPackage() // <-- Add this line
);
}
};
// ...
}

Update Android Manifest

Add the following to android/app/src/main/AndroidManifest.xml:

Within the application component, add the messaging service and instance ID service:

<application ...>
<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application>

(Optional) Background Messages

If you want to be able to react to data-only messages when your app is in the background, e.g. to display a heads up notification, then you need to add the following to android/app/src/main/AndroidManifest.xml:

<application ...>
<service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />
</application>

Install the RNFirebase Notifications package

Add the RNFirebaseNotificationsPackage to your android/app/src/main/java/com/[app name]/MainApplication.java:

// ...
import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage; // <-- Add this line
public class MainApplication extends Application implements ReactApplication {
// ...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNFirebasePackage(),
new RNFirebaseNotificationsPackage() // <-- Add this line
);
}
};
// ...
}

Update Android Manifest

Add the following to android/app/src/main/AndroidManifest.xml:

Add permissions:

<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />

Set app launch mode inside activity props:

<activity ...
android:launchMode="singleTop"
>

Scheduled Notifications (Optional)

If you would like to schedule local notifications then you also need to add the following to the application component of android/app/src/main/AndroidManifest.xml:

<application ...>
<receiver android:name="io.invertase.firebase.notifications.RNFirebaseNotificationReceiver"/>
<receiver android:enabled="true" android:exported="true" android:name="io.invertase.firebase.notifications.RNFirebaseNotificationsRebootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>

Code for Notifications:

Before integrating the code please install the following dependencies:

yarn add @react-native-community/async-storage

Add the following code to App.js file

import React from 'react';
import {View, Alert} from 'react-native';
import {styles} from './styles';
import firebase from 'react-native-firebase';
import Dash from './Dashboard';
export default class App extends React.Component {componentDidMount() {
// Create notification channel required for Android devices
this.createNotificationChannel();
// Ask notification permission and add notification listener
this.checkPermission();
}
createNotificationChannel = () => {
// Build a android notification channel
const channel = new firebase.notifications.Android.Channel(
'reminder', // channelId
'Reminders Channel', // channel name
firebase.notifications.Android.Importance.High, // channel importance
).setDescription('Used for getting reminder notification'); // channel description
// Create the android notification channel
firebase.notifications().android.createChannel(channel);
};
checkPermission = async () => {
const enabled = await firebase.messaging().hasPermission();
if (enabled) {
// We've the permission
this.notificationListener = firebase
.notifications()
.onNotification(async notification => {
// Display your notification
await firebase.notifications().displayNotification(notification);
console.log(notification);
});
} else {
// user doesn't have permission
try {
await firebase.messaging().requestPermission();
} catch (error) {
Alert.alert(
'Unable to access the Notification permission. Please enable the Notification Permission from the settings',
);
}
}};
render() {
return (
<View style={styles.container}>
<Dashboard />
</View>
);}}

Dashboard code for the Front end:

/* eslint-disable react-native/no-inline-styles */
import React, {useState, useEffect} from 'react';
import {SafeAreaView,Text,Platform,View,TouchableOpacity} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import DateTimePicker from 'react-native-modal-datetime-picker';
import moment from 'moment';
import firebase from 'react-native-firebase';
import {styles} from './styles';
const Dashboard = () => {
const [showTimer, setShowTimer] = useState(false);
const [reminderTime, setReminderTime] = useState(moment({hour: 17}));
useEffect(() => {
async function setReminder() {
await firebase.notifications().cancelAllNotifications();
// schedule notification
await firebase.notifications().scheduleNotification(buildNotification(), {
fireDate: reminderTime.valueOf(),
repeatInterval: 'day',
exact: true,
});
}setReminder();
}, [reminderTime]);
useEffect(() => {retrieveData();}, []);const buildNotification = () => {
const title = Platform.OS === 'android' ? 'Daily reminder' : 'Trip Planner Reminder';
const notification = new firebase.notifications.Notification().setNotificationId('1') // Any random ID
.setTitle(title) // Title of the notification
.setBody('red is blue') // body of notification
.android.setPriority(firebase.notifications.Android.Priority.High) // set priority in Android
.android.setChannelId('reminder') // should be the same when creating channel for Android
.android.setAutoCancel(true); // To remove notification when tapped on it
return notification;
};
const showDateTimePicker = () => {
setShowTimer(true);
};
const hideDateTimePicker = () => {
setShowTimer(false);
};
const handleDatePicked = async time => {
await AsyncStorage.setItem('time', JSON.stringify(time));
setReminderTime(moment(time));
hideDateTimePicker();
};
const retrieveData = async () => {
try {
const valueString = await AsyncStorage.getItem('time');
const value = JSON.parse(valueString);
if (value !== null) {
setReminderTime(moment(value));
}} catch (error) {console.log(error);}};
return (
<SafeAreaView style={styles.container}>
<View style={styles.row}>
<Text style={styles.title}>Reminder Time:</Text>
<Text style={styles.text}>{reminderTime.format('LT')}</Text>
</View>
<TouchableOpacity onPress={showDateTimePicker} style={styles.btn}>
<Text>Update reminder time here</Text></TouchableOpacity></View>
<DateTimePicker isVisible={showTimer} onConfirm={handleDatePicked}onCancel={hideDateTimePicker} mode="time" date={new Date()} is24Hour={false} titleIOS="Select a reminder time" /></SafeAreaView>
);};
export default Dashboard;

Conclusion: The code given above would provide you a timer to choose the time and you just need to add the time and wait for the exact time for Notification reminder. For iOS the app would show reminder in foreground whereas in the android notifications would be visible only in Background.

Let me know if you have any questions. Also if there is an error in the code.

--

--