Getting Started with React Native
What are Push Notifications?
Push notifications are the most cost-efficient way to increase user engagement for an application and keep users updated. Today’s mobile apps extensively use push notifications irrespective of their domains. As per an analysis, opt-in rates for app push notifications on Android ranges from 49% to 95%, with a medium equal to 81%, and on the iOS side, it ranges from 29% to 73%, with a medium equal to 51%.
Push notifications are alerts that the users receive in real-time on their device no matter if the app is running or not. There are 2 major categories of push notifications:
- Local notification
- Remote push notification
Further, the remote push notification could be categorized as silent or noisy notification. The former does not show the alert in the notification tray and could be used to trigger some processes in background while the latter displays an alert in the notification tray.
Remote push notifications could be sent using one of the below services:
- Apple Push Notification Service
- Expo Push Notification Service
- Firebase Cloud Messaging
To send push notifications to a react native application, we need to register the app using a token which is a string that uniquely identifies each device. We can store this token in our database and map each token with a user. Since this token is mapped to a device in the frontend, we have to handle the updation and deletion of this token on, token expiry and signing out of the user.
In this blog, we’ll create a sample react-native project (expo bare workflow) and implement push notifications using firebase.
Project setup
1. Initialize a react native project (bare workflow) using expo init
.
2. Install firebase core dependencies for push notifications
- npm i @react-native-firebase/app
- npm i @react-native-firebase/messaging
- npx pod-install
(for install cocoa-pods in iOS)
3. Create a firebase project
Android
1. Add an android app to your newly created firebase project.
The android package name is a unique identifier for your application. You can find the value in the AndroidManifest.xml file.
2. Download the google-services.json file from the next step and place it inside android/app
.
3. Update the native files for adding dependencies.
- android/build.gradle
buildscript {
ext {
buildToolsVersion = "29.0.3"
minSdkVersion = 21
compileSdkVersion = 30
targetSdkVersion = 30
}
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:4.1.0")
classpath 'com.google.gms:google-services:4.3.8' // New dependency added
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
- android/app/build.gradle
apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services' // New plugin added
import com.android.build.OutputFile
iOS
1. Add an iOS app to your newly created firebase project.
The iOS bundle id is the unique identifier for the application that will be registered with apple.
2. Download the GoogleService-info.plist from the next step and open the iOS project in XCode.
3. Verify that the bundle id is the same as of the firebase app. (If not update the identifier)
4. Right click on the project and select Add Files to “project name”
5. Add the downloaded GoogleService-info.plist
6. In the AppDelegate.m
import firebase and initialize firebase app
#import <React/RCTLinkingManager.h>
#import <Firebase.h> // import firebase dependency
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// initializing firebase app
if ([FIRApp defaultApp] == nil) {
[FIRApp configure];
}
Getting permissions
iOS
1. In XCode, under Signing & Capabilities
, add Push Notifications and Background Modes capability. Under Background Modes, select background fetch and remote notifications options.
2. Head over to the Certificates,Identifiers & Profiles section in the apple developer portal and create a new key. Select the Apple Push Notification Service and then continue and download the key.
3. Upload the downloaded key in the firebase project settings.
Now, since we have completed all the setup, we’ll proceed to the mobile code to fetch the required permissions.
- In the starting point of your react native project (App.tsx), add the code to request access.
// getting push notification permission
useEffect(() => {
messaging().requestPermission()
}, [])
Getting push token
useEffect(() => {
// get the device token on app load
messaging()
.getToken()
.then(token => {
setToken(token)
})
// Setup a listener so that if the token is refreshed while the
// app is in memory we get the updated token.
return messaging().onTokenRefresh(token => {
setToken(token)
})
}, [])
Backend setup
const payload = {
notification: {
title: "Push Notification",
body: "This is push notification sent dynamically from backend 🤩",
sound: "default",
},
}
await admin.messaging().sendToDevice(token, payload, {
contentAvailable: true,
priority: "high",
})
Token in the sendToDevice method is the destination token. By default data-only notifications do not show alerts on the device therefore we explicitly make the notification’s priority high and content available as true for android and iOS to show the alert.
Sending and receiving notification
// send the notification
const sendNotification = async () => {
Alert.alert(
"Notification sent",
"The destination will receive the notification"
)
try {
await axios.post(
"https://9d9gmb4jmd.execute-api.us-east-1.amazonaws.com/dev/",
{ token }
)
} catch (error) {
console.log("Error", error)
}
}
We’ll send the destination token to our backend endpoint to send the notification.
By default the push notification does not appear when the app is in foreground. To handle the scenario, we need to listen to the incoming notification.
// handling foreground notifications
useEffect(() => {
const unsubscribe = messaging().onMessage(async (remoteMessage = {}) => {
const notification = remoteMessage.notification || {}
const title = notification.title
const body = notification.body
if (title) {
Alert.alert(title, body)
}
})
return unsubscribe
}, [])
This will show an alert once we receive the notification.
App Screenshots
Conclusion
- To setup push notifications in iOS, you need a developer account
- iOS simulator does not support push notifications. The flow needs to be tested on a real device.
- For android emulators, you need to be signed in with a google account for the push notifications to work.
- For advanced workflows and customizations, you can use react-native-push-notification package
For more information refer to the react native firebase docs.
Source Code
React-native: https://github.com/antstackio/rn-push-notification-demo
Backend: https://github.com/antstackio/push-notification-lambda