Detect if the app was launched/opened from a push notification describes how to detect whether a native iOS app was opened (that is, either launched or merely made active) via the user tapping a push notification.
How can I do the same thing in React Native? PushNotificationIOS
lets me attach a notification listener...
PushNotificationIOS.addEventListener('notification', function (notification) {
console.log('got a notification', notification);
});
but this fires both when a push notification is received with the application in the foreground, and when I open the app via a push notification.
How can I detect the second case in particular?
There are two cases here that need to be detected in different ways:
React.PushNotificationIOS.getInitialNotification
method.UIApplicationStateInactive
state (or 'background'
state, as React Native's AppStateIOS
class calls it).Code to handle both cases (you can put this in your index.ios.js
or somewhere else that's run on app launch):
import React from 'react';
import { PushNotificationIOS, AppState } from 'react-native';
function appOpenedByNotificationTap(notification) {
// This is your handler. The tapped notification gets passed in here.
// Do whatever you like with it.
console.log(notification);
}
PushNotificationIOS.getInitialNotification().then(function (notification) {
if (notification != null) {
appOpenedByNotificationTap(notification);
}
});
let backgroundNotification;
PushNotificationIOS.addEventListener('notification', function (notification) {
if (AppState.currentState === 'background') {
backgroundNotification = notification;
}
});
AppState.addEventListener('change', function (new_state) {
if (new_state === 'active' && backgroundNotification != null) {
appOpenedByNotificationTap(backgroundNotification);
backgroundNotification = null;
}
});
getInitialNotification
does not work with Local Notifications.Unfortunately, as of 0.28 of React Native, using PushNotificationIOS.getInitialNotification()
always returns a null
value when being launched by a Local Push Notification.
Because of that, you need to catch the push notification as a launchOption
in your AppDelegate.m
and pass it into React Native as an appProperty
.
Here's all that you need to receive a Local Push Notification from a cold launch or from the background/inactive state.
AppDelegate.m
(Native iOS Code)
// Inside of your didFinishLaunchingWithOptions method...
// Create a Mutable Dictionary to hold the appProperties to pass to React Native.
NSMutableDictionary *appProperties = [NSMutableDictionary dictionary];
if (launchOptions != nil) {
// Get Local Notification used to launch application.
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification) {
// Instead of passing the entire Notification, we'll pass the userInfo,
// where a Record ID could be stored, for example.
NSDictionary *notificationUserInfo = [notification userInfo];
[ appProperties setObject:notificationUserInfo forKey:@"initialNotificationUserInfo" ];
}
}
// Your RCTRootView stuff...
rootView.appProperties = appProperties;
index.ios.js
(React Native)
componentDidMount() {
if (this.props.initialNotificationUserInfo) {
console.log("Launched from Notification from Cold State");
// This is where you could get a Record ID from this.props.initialNotificationUserInfo
// and redirect to the appropriate page, for example.
}
PushNotificationIOS.addEventListener('localNotification', this._onLocalNotification);
}
componentWillUnmount() {
PushNotificationIOS.removeEventListener('localNotification', this._onLocalNotification);
}
_onLocalNotification( notification ) {
if (AppState.currentState != 'active') {
console.log("Launched from Notification from Background or Inactive state.");
}
else {
console.log("Not Launched from Notification");
}
}
Make sure to import PushNotificationIOS
and AppState
from react-native
.
I haven't tested this with Remote Push Notifications. Perhaps @MarkAmery's method works just fine with Remote Push Notifications but, unfortunately, as of current state of React Native, this is the only way I was able to get Local Push Notifications from a cold state working.
This is highly undocumented in React Native so I have created an issue on their GitHub repo to draw attention to it and hopefully rectify it. If you're dealing with this, go there and give it a thumbs up so it percolates to the top.
https://github.com/facebook/react-native/issues/8580
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With