The documentation that follows assumes you have generated a React Native Android project using the react-native-cli
, i.e.:
react-native init ReactNativeAzureNotificationHubSample
In addition to the standard React Native requirements, you will also need to install the following Android SDK components with your prefered SDK management tools:
- Google Play services
npm install react-native-azurenotificationhub
- Log on to the Azure Portal and create a new Notification Hub.
- Log in to the Firebase console and create a new Firebase project if you don't already have one.
- After your project is created click Add Firebase to your Android app and follow the instructions provided.
- In the Firebase Console, click the cog for your project and then click Project Settings
-
Click the Cloud Messaging tab in your project settings and copy the value of the Server key and Sender ID. The former will be used to configure the Notification Hub Access Policy and the latter for your React Native module registration.
-
Back on the Azure Portal page for your notification hub, select Settings > Notification Services > Google (GCM). Enter the FCM Server key you copied from the Firebase console and click Save.
In android/app/src/main/AndroidManifest.xml
<application
xmlns:tools="http://schemas.android.com/tools"
tools:replace="android:icon,android:allowBackup"
...>
</application>
This resolves the error caused by the manifest merger tool for gradle.
In android/build.gradle
...
buildscript {
...
dependencies {
...
classpath("com.google.gms:google-services:4.2.0")
}
}
allprojects {
repositories {
...
maven { url 'https://dl.bintray.com/microsoftazuremobile/SDK' }
}
}
In android/app/build.gradle
...
dependencies {
...
implementation project(":react-native-azurenotificationhub") // <- Note only include this line if using a version of RN < 0.60 since it will be auto linked
implementation "com.google.firebase:firebase-messaging:17.6.0"
implementation "com.google.firebase:firebase-core:16.0.8"
}
apply plugin: "com.google.gms.google-services"
In android/app/src/main/AndroidManifest.xml
...
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application ...>
...
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<service
android:name="com.azure.reactnative.notificationhub.ReactNativeRegistrationIntentService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<service
android:name="com.azure.reactnative.notificationhub.ReactNativeFirebaseMessagingService"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<activity
android:launchMode="singleTop"
...>
</activity>
...
If using a version of React Native before RN 0.60 that does not support autolinking:
In android/settings.gradle
...
include ':react-native-azurenotificationhub'
project(':react-native-azurenotificationhub').projectDir = file('../node_modules/react-native-azurenotificationhub/android')
Register the module package in MainApplication.java
import com.azure.reactnative.notificationhub.ReactNativeNotificationHubPackage;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new ReactNativeNotificationHubPackage() // <-- Add this package
);
}
};
...
}
On the Azure Portal page for your notification hub, copy a connection string from Settings > Access Policies.
The example below shows how you can register and unregister from Azure Notification Hub in your React Native component.
import React, { Component } from 'react';
import { NativeEventEmitter } from 'react-native';
import {
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
const NotificationHub = require('react-native-azurenotificationhub');
const PushNotificationEmitter = new NativeEventEmitter(NotificationHub);
const EVENT_AZURE_NOTIFICATION_HUB_REGISTERED = 'azureNotificationHubRegistered';
const EVENT_AZURE_NOTIFICATION_HUB_REGISTERED_ERROR = 'azureNotificationHubRegisteredError';
const EVENT_REMOTE_NOTIFICATION_RECEIVED = 'remoteNotificationReceived';
const connectionString = '...'; // The Notification Hub connection string
const hubName = '...'; // The Notification Hub name
const senderID = '...'; // The Sender ID from the Cloud Messaging tab of the Firebase console
const tags = [ '...' ]; // The set of tags to subscribe to. See notes after code sample
const channelName = '...'; // The channel's name (optional)
const channelDescription = '...'; // The channel's description (optional)
const channelImportance = 3; // The channel's importance (NotificationManager.IMPORTANCE_DEFAULT = 3) (optional)
// Notes:
// 1. Setting this value to 4 enables heads-up notification on Android 8
// 2. On some devices such as Samsung Galaxy, changing this value requires
// uninstalling/re-installing the app to take effect.
const channelShowBadge = true; // Optional
const channelEnableLights = true; // Optional
const channelEnableVibration = true; // Optional
const template = '...'; // Notification hub templates:
// https://docs.microsoft.com/en-us/azure/notification-hubs/notification-hubs-templates-cross-platform-push-messages
const templateName = '...'; // The template's name
export default class App extends Component {
constructor(props) {
super(props);
PushNotificationEmitter.addListener(EVENT_REMOTE_NOTIFICATION_RECEIVED, this._onRemoteNotification);
}
register() {
PushNotificationEmitter.addListener(EVENT_AZURE_NOTIFICATION_HUB_REGISTERED, this._onAzureNotificationHubRegistered);
PushNotificationEmitter.addListener(EVENT_AZURE_NOTIFICATION_HUB_REGISTERED_ERROR, this._onAzureNotificationHubRegistrationError);
NotificationHub.register({
connectionString,
hubName,
senderID,
tags,
channelName,
channelDescription,
channelImportance,
channelShowBadge,
channelEnableLights,
channelEnableVibration
})
.then(console.log)
.catch(console.warn);
}
registerTemplate() {
PushNotificationEmitter.addListener(EVENT_AZURE_NOTIFICATION_HUB_REGISTERED, this._onAzureNotificationHubRegistered);
PushNotificationEmitter.addListener(EVENT_AZURE_NOTIFICATION_HUB_REGISTERED_ERROR, this._onAzureNotificationHubRegistrationError);
NotificationHub.registerTemplate({
connectionString,
hubName,
senderID,
template,
templateName,
tags,
channelName,
channelDescription,
channelImportance,
channelShowBadge,
channelEnableLights,
channelEnableVibration
})
.then(console.log)
.catch(console.warn);
}
getInitialNotification() {
NotificationHub.getInitialNotification()
.then(console.log)
.catch(console.warn);
}
getUUID() {
NotificationHub.getUUID(false)
.then(console.log)
.catch(console.warn);
}
isNotificationEnabledOnOSLevel() {
NotificationHub.isNotificationEnabledOnOSLevel()
.then(console.log)
.catch(console.warn);
}
unregister() {
NotificationHub.unregister()
.then(console.log)
.catch(console.warn);
}
unregisterTemplate() {
NotificationHub.unregisterTemplate(templateName)
.then(console.log)
.catch(console.warn);
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.register.bind(this)}>
<View style={styles.button}>
<Text style={styles.buttonText}>
Register
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.registerTemplate.bind(this)}>
<View style={styles.button}>
<Text style={styles.buttonText}>
Register Template
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.getInitialNotification.bind(this)}>
<View style={styles.button}>
<Text style={styles.buttonText}>
Get initial notification
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.getUUID.bind(this)}>
<View style={styles.button}>
<Text style={styles.buttonText}>
Get UUID
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.isNotificationEnabledOnOSLevel.bind(this)}>
<View style={styles.button}>
<Text style={styles.buttonText}>
Check if notification is enabled
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.unregister.bind(this)}>
<View style={styles.button}>
<Text style={styles.buttonText}>
Unregister
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.unregisterTemplate.bind(this)}>
<View style={styles.button}>
<Text style={styles.buttonText}>
Unregister Template
</Text>
</View>
</TouchableOpacity>
</View>
);
}
_onAzureNotificationHubRegistered(registrationID) {
console.warn('RegistrationID: ' + registrationID);
}
_onAzureNotificationHubRegistrationError(error) {
console.warn('Error: ' + error);
}
_onRemoteNotification(notification) {
console.warn(notification);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#FFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#FFF',
marginBottom: 5,
},
button: {
backgroundColor: '#0071c9',
borderRadius: 4,
justifyContent: 'center',
alignItems: 'center',
padding: 14,
marginVertical: 14,
},
buttonText: {
color: '#FFF',
},
});
Azure Notification Hubs uses "tags" to target notifications. To receive targeted notifications, a device subscribes to those tags when registering (they are sent in an array by the register
and registerTemplate
methods above). So, if you want to send a notification to one device, that device must register on a unique tag, and report that tag to your backend, where it can be associated with your user. This is a contrast to other notification platforms, which often give you a unique ID during the registration process for this purpose.
Needing to supply your own unique, non-random string (you'll want it again when you unregister the device in your backend) could lead to the temptation to use the device's unique identifier (device ID/UDID) to register for notifications. There are numerous privacy and security reasons not to do this.