目次
概要
React Nativeで開発したアプリも普通のアプリなのでプッシュメッセージ(Push Message)を受けることができます。このブログポストではReact Nativeで開発したアプリへプッシュメッセージ(Push Message)を受けるためreact-native-firebase(V5)
ライブラリでFCM(Firebase Cloud Messaging)
を使う方法について説明します。
- react-native-firebase v5: https://v5.rnfirebase.io/
- FCM(Firebase Cloud Messaging): https://firebase.google.com/docs/cloud-messaging
ライブラリインストール
下記のコマンドを使ってreact-native-firebaseのライブラリをインストールします。
npm install --save react-native-firebase
ライブラリリンク
react-native-firebaseライブラリを使うためにはライブラリをリンクする必要があります。
0.60以上
下記のコマンドを使ってreact-native-firebaseライブラリをReact Nativeプロジェクトへ連結します。
cd ios
pod install
cd ..
0.59以下
下記のコマンドを使ってreact-native-firebaseライブラリをReact Nativeプロジェクトへ連結します。
react-native link react-native-firebase
Firebaseプロジェクト生成
次はGoogleのファイアベース(Google Firebase)でプロジェクトを生成する必要があります。下記のリンクを押してGoogleのファイアベース(Google Firebase)へ移動します。
- Googleのファイアベース(Google Firebase): https://firebase.google.com
右上のSIGN IN
ボタンを押してログインします。
ログインをしたら、右上のGO TO CONSOLE
を押してGoogleのファイアベースコンソール(Google Firebase Console)へ移動します。
Googleのファイアベースコンソール(Google Firebase Console)で+ Add project
を押してプロジェクトを追加します。
プロジェクトの情報を追加した後、Create project
ボタンを押してプロジェクトを生成します。
iOS設定
react-native-firebaseを使うためiOSを設定する方法について説明します。
Firbase iOSプロジェクトの設定
Googleのファイアベースコンソール(Google Firebase Console)でプロジェクトを選択したら下記のような画面が確認できます。
真ん中にあるiOS
ボランを押してiOS設定画面へ移動します。
開発したアプリのBundle IDを入力してRegister app
ボタンを押します。
Googleのファイアベース(Google Firebase)が生成したGoogleService-Info.plist
ファイルをダウンロードして、info.plist
と同じ位置へ追加します。GoogleService-Info.plist
ファイル追加が終わったら、Next
ボタンを押します。
画面へ表示された形でGoogleファイアベースSDK(Google Firebase SDK)をReact Nativeプロジェクトへ追加します。
React Nativeのバージョンが0.59以下の場合、下記のコマンドを実行します。
pod init
GoogleのファイアベースSDK(Google Firebase SDK)を./ios/Podfile
へ追加します。
target 'blaboo' do
...
pod 'Firebase/Core'
pod 'Firebase/Analytics' // if you use Analytics
pod 'Firebase/Messaging'
...
end
GoogleのファイアベースSDK(Google Firebase SDK)をインストールします。
pod install
# pod update
React NativeプロジェクトのAppDelegate.m
ファイルへ下記のようにソースコードを追加します。
...
@import Firebase;
#import "RNFirebaseNotifications.h"
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[RNFirebaseNotifications configure];
...
return YES;
}
...
GoogleのファイアベースSDK(Google Firebase SDK)を初期化します。
私はこの部分はSkip this step
を押してスキップしました。
権限の設定
権限の設定をするためios/[project name].xcworkspace
ファイルを選択してXcodeを実行します。
上にある+Capabilty
を選択して下記の内容を検索して追加します。
- Push Notifications
- Background modes
Background modesを追加するとPush Notificationsと違ってチェックボックスのリストが確認できます。その中でRemote notifications
を選択します。
APNS設定
iOSでプッシュメッセージを使うためにはAPNS(Apple Push Notification Service)
を設定する必要があります。
macOSでKeychain Access
を実行します。そしてKeychain Access
> Certificate Assistant
> Request a Certificate From a Certificate Authority...
のメニューを選択します。
下記のような画面が出るとUser Email Address
とCommon Name
を入力した後、Saved to disk
を選択してContinue
ボタンを選択します。
下記のような画面が出ると、保存したいフォルダを指定してSave
ボタンを押して保存します。
その後、https://developer.apple.com/サイトへ移動します。
その後、右上のAccount
メニューを選択してログインします。下記のような画面が出ると左メニューにあるCertificates, Identifiers & Profiles
を選択します。
下記のような画面が見えるとCertificates
メニューを押して、上にある+
ボタンを押します。
その後、Create a New Certificate
の画面が出ると、スクロールして下に移動します。下に移動すると下記のようにService
のセクションにあるApple Push Notification service SSL (Sandbox & Production)
を見つけれます。その項目を選択して右上のContinue
ボタンを押して次へ移動します。
次と同じ画面が出ると、FCMメッセージを使いたいアプリを選択して、右上のContinue
ボタンを押して次へ進めます。
次のようにファイルを選択する画面が出るとChoose File
を選択してKeychainで作ったファイルを選択します。選択したら、右上のContinue
ボタンを選択します。
次のような画面が出ると、無事に証明書が生成されました。右上のDownload
ボタンを押して、生成した証明書をダウンロードします。
このようにダウンロードした証明書を.p12
の形式で変換する必要があります。ダウンロードした証明書をダブルクリックしてKeychainへ登録します。
登録された証明書をマウスの右クリックした後、Export "Apple Push Services: package name"...
を選択します。
上のようにファイルを保存する画面が出るとFile Format
へPersonal Information Exchange (.p12)
が選択された状態でSave
を押してファイルを保存します。
p12ファイルを保存するため、上のようにパスワードを入力する必要があります。パスワードを入力したら.p12ファイル形式で保存します。
また、Firebase Consoleへ移動して、上で作ったプロジェクトを選択します。プロジェクトを選択したら右へ上で作ったiOS
のプロジェクトが確認できます。
iOSプロジェクトを選択して設定アイコンを押してiOSプロジェクトの設定画面へ移動します。iOSの設定画面の上にあるCloud Messaging
のメニューを押します。
下へiOS app configuration
のセクションのAPNs certificates
の項目が確認できます。No development APNs certificate
とNo production APNs certificate
の横にあるUpload
ボタンを押します。
この画面で上で作った.p12
ファイルをアップロードして、.p12
を保存する時使ったパスワードを入力します。
これでAPNS(Apple Push Notification Service)の設定は完了しました。
アンドロイド設定
今からreact-native-firebaseを使うためアンドロイドを設定する方法について説明します。
アンドロイドパッケージ名修正
React Nativeプロジェクトのフォルダで
android/app/BUCK
ファイルを修正... android_build_config( ... package = "package_name", ) ... android_resource( ... package = "package_name", ... ) ...
React Nativeプロジェクトフォルダにある
android/app/src/main/AndroidManifest.xml
ファイルを修正<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="package_name"> ...
React Nativeプロジェクトフォルダにある
android/app/src/main/java/com/ProjectName/MainActivity.java
ファイルを修正package package_name; ...
React Nativeプロジェクトフォルダにある
android/app/src/main/java/com/ProjectName/MainApplication.java
ファイル修正package package_name; ...
React Nativeプロジェクトフォルダにある
android/app/build.gradle
ファイル修正... defaultConfig { applicationId package_name ... } ...
Firbase アンドロイドプロジェクト設定
Googleのファイアベースコンソール(Google Firebase Console)の左上のProject Overview
を選択します。
上にある+ Add app
> アンドロイドアイコン
を押してアンドロイド(Android)プロジェクト設定へ移動します。
アンドロイドパッケージ名(Android Package Name)を入力してRegister app
を選択します。
Googleのファイアベース(Google Firebase)が作ったgoogle-services.json
ファイルをReact Nativeプロジェクトのandroid/app
フォルダへコピーします。そして、Next
ボタンを押して次へ進めます。
React Nativeプロジェクトがあるフォルダへandroid/build.gradle
ファイルを開いて下記のようにコードを追加します。
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:3.4.2")
classpath 'com.google.gms:google-services:4.3.3'
}
}
...
allprojects {
repositories {
mavenLocal()
google()
jcenter()
...
}
}
上のようにrepositories
へgoogle()
があるか確認して、jcenter()
より上に宣言されてるか確認します。
React Nativeプロジェクトがあるフォルダでandroid/app/build.gradle
ファイルを開いて下記のようにコードを追加します。
dependencies {
// under 59 version
// implementation project(':react-native-firebase')
...
implementation 'com.google.android.gms:play-services-base:17.2.1'
implementation 'com.google.firebase:firebase-core:17.0.0'
implementation "com.google.firebase:firebase-messaging:20.0.0"
implementation 'me.leolin:ShortcutBadger:1.1.21@aar'
}
そして同じファイルの一番下へ下記のようにコードを追加します。
...
apply plugin: 'com.google.gms.google-services'
次は./android/build.gradle
ファイルを開いて下記のように修正します。
buildscript {
ext {
...
}
repositories {
...
}
dependencies {
classpath("com.android.tools.build:gradle:3.4.2")
classpath 'com.google.gms:google-services:4.3.3'
}
}
- 0.60以上
react-native-firebaseを使うためandroid/app/src/main/java/com/[app name]/MainApplication.java
ファイルを開いて下記のように修正します。
import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.analytics.RNFirebaseAnalyticsPackage;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;
...
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new RNFirebaseAnalyticsPackage());
packages.add(new RNFirebaseMessagingPackage());
packages.add(new RNFirebaseNotificationsPackage());
return packages;
}
...
- 0.59以下
react-native-firebaseを使うためandroid/app/src/main/java/com/[app name]/MainApplication.java
ファイルを開いて下記のように修正します。
import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.analytics.RNFirebaseAnalyticsPackage;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
...
new RNFirebasePackage(),
new RNFirebaseAnalyticsPackage(),
new RNFirebaseMessagingPackage()
...
);
}
アンドロイドでメッセージを受けるためandroid/app/src/main/AndroidManifest.xml
ファイルを開いて下記のように修正します。
<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.RNFirebaseBackgroundMessagingService" />
...
</application>
アンドロイドスタジオ(Android Studio)を開いてGradle Sync
をします。
テスト
FCMの設定が上手くできたかテストしてみましょう。
Javascriptソースコード追加
テストをするためにはFCM Tokenが必要です。このトークンを取得するためにはJavascriptを利用しなきゃならないです。ここで紹介してるソースコードは実際プロジェクトでも使えます。
FCMを使うため./src/Components/FCMContainer/index.tsx
ファイルを開いて下記のように修正します。
import React, { useEffect } from 'react';
import { Platform, Alert } from 'react-native';
import firebase from 'react-native-firebase';
import DeviceInfo from 'react-native-device-info';
import AsyncStorage from '@react-native-async-storage/async-storage';
import Axios from 'axios';
import Config from '~/Config';
interface Props {
children: JSX.Element;
onNotificationOpened?: (data: { [key: string]: string }) => any;
}
const FCMContainer = ({ children, onNotificationOpened }: Props): JSX.Element => {
const CHANNEL_ID = 'io.github.dev.yakuza.poma';
const APP_NAME = 'POMA';
const DESCRIPTION = 'POMA channel';
let _onTokenRefreshListener: any = undefined;
let _notificationDisplayedListener: any = undefined;
let _notificationListener: any = undefined;
let _notificationOpenedListener: any = undefined;
const _registerMessageListener = (): void => {
firebase
.notifications()
.getInitialNotification()
.then((notificationOpen) => {
if (
onNotificationOpened &&
typeof onNotificationOpened === 'function' &&
notificationOpen &&
notificationOpen.notification &&
notificationOpen.notification.data &&
notificationOpen.notification.data.notifications_id
) {
onNotificationOpened(notificationOpen.notification.data);
}
});
const channel = new firebase.notifications.Android.Channel(
CHANNEL_ID,
APP_NAME,
firebase.notifications.Android.Importance.Max,
).setDescription(DESCRIPTION);
firebase.notifications().android.createChannel(channel);
_notificationListener = firebase.notifications().onNotification((notification) => {
// Process your notification as required
notification.android.setPriority(firebase.notifications.Android.Priority.Max);
notification.android.setChannelId(CHANNEL_ID);
firebase.notifications().displayNotification(notification);
});
_notificationDisplayedListener = firebase.notifications().onNotificationDisplayed(() => {});
_notificationOpenedListener = firebase
.notifications()
.onNotificationOpened((notificationOpen) => {
if (onNotificationOpened && typeof onNotificationOpened === 'function') {
onNotificationOpened(notificationOpen.notification.data);
}
});
};
const _registerToken = async (fcmToken: string): Promise<void> => {
console.log(fcmToken);
// try {
// const deviceUniqueId = DeviceInfo.getUniqueId();
// const token = await AsyncStorage.getItem('token');
// await Axios.post(
// `URL`,
// {
// token: fcmToken,
// device_unique_id,
// },
// {
// headers: { Authorization: 'Bearer ' + token },
// },
// );
// } catch (error) {
// console.log('ERROR: _registerToken');
// console.log(error.response.data);
// }
};
const _registerTokenRefreshListener = (): void => {
if (_onTokenRefreshListener) {
_onTokenRefreshListener();
_onTokenRefreshListener = undefined;
}
_onTokenRefreshListener = firebase.messaging().onTokenRefresh((fcmToken) => {
// Process your token as required
_registerToken(fcmToken);
});
};
const _updateTokenToServer = async (): Promise<void> => {
try {
const fcmToken = await firebase.messaging().getToken();
_registerMessageListener();
_registerToken(fcmToken);
} catch (error) {
console.log('ERROR: _updateTokenToServer');
console.log(error);
}
};
const _requestPermission = async (): Promise<void> => {
try {
// User has authorised
await firebase.messaging().requestPermission();
await _updateTokenToServer();
} catch (error) {
// User has rejected permissions
Alert.alert("you can't handle push notification");
}
};
const _checkPermission = async (): Promise<void> => {
try {
const enabled = await firebase.messaging().hasPermission();
if (enabled) {
// user has permissions
_updateTokenToServer();
_registerTokenRefreshListener();
} else {
// user doesn't have permission
_requestPermission();
}
} catch (error) {
console.log('ERROR: _checkPermission', error);
console.log(error);
}
};
useEffect(() => {
_checkPermission();
return (): void => {
if (_onTokenRefreshListener) {
_onTokenRefreshListener();
_onTokenRefreshListener = undefined;
}
if (_notificationDisplayedListener) {
_notificationDisplayedListener();
_notificationDisplayedListener = undefined;
}
if (_notificationListener) {
_notificationListener();
_notificationListener = undefined;
}
if (_notificationOpenedListener) {
_notificationOpenedListener();
_notificationOpenedListener = undefined;
}
};
}, []);
if (Platform.OS === 'ios') {
firebase.notifications().setBadge(0);
}
return children;
};
export default FCMContainer;
上のソースコードで皆さんのChannel ID
とApp Name
、Description
で修正します。
const CHANNEL_ID = 'io.github.dev.yakuza.poma';
const APP_NAME = 'POMA';
const DESCRIPTION = 'POMA channel';
また、テストのためFCM Tokenをローグで表示しますが、
const _registerToken = async (fcmToken: string): Promise<void> => {
console.log(fcmToken);
// try {
// const deviceUniqueId = DeviceInfo.getUniqueId();
// const token = await AsyncStorage.getItem('token');
// await Axios.post(
// `URL`,
// {
// token: fcmToken,
// device_unique_id,
// },
// {
// headers: { Authorization: 'Bearer ' + token },
// },
// );
// } catch (error) {
// console.log('ERROR: _registerToken');
// console.log(error.response.data);
// }
};
実際使うときは、この部分でサーバと通信してFCM Tokenを保存します。
上のソースコードを使うためにはApp.tsx
ファイルを開いて下記のように修正します。
import React from 'react';
import FCMContainer from '~/Component/FCMContainer';
const App = (): JSX.Element => {
return (
<FCMContainer>
...
</FCMContainer>
);
};
export default App;
iOSテスト
iOSでFCMをテストするためには端末が必要です。端末を連結してXcode
を実行します。
Xcodeが実行されると左上のメニューで端末を選択して>
ボタンを押してプロジェクトを実行します。
端末でアプリが実行されると下記のようにPush Notificationの権限を許可するか聞いてくれる画面がでます。Allow
ボタンを押して許可します。
許可するとコンソールへ上のようにFCM Tokenが出力されます。そのTokenをコピーします。
次はFirebase Consoleを接続した後、左メニュでCloud Messaging
を選択してSend your first message
ボタンを押します。
次のような画面が出るとNotification title
とNotification text
へテストメッセージを作成します。作成が完了されたら、右にあるSend test message
を選択します。
次のような画面が出るとAdd an FCM registration token
に上でコピーしたFCM Tokenを入力して+
ボタンを選択します。
その後、Test
ボタンを押してテストメッセージを送信してみます。
そしたら下記のように端末へメッセージがうまく受信されることが確認できます。
アンドロイドテスト
アンドロイドでFCMをテストするため下記のコマンドを使ってアンドロイド実行します。
npm run android
実行が完了されたら、下記のようにコンソールへFCM Tokenに出力されることが確認できます。そのキーをコピーします。
次はFirebase Consoleへ移動して、左メニューでCloud Messaging
を選択してSend your first message
ボタンを押します。
次のような画面が出るとNotification title
とNotification text
にテストメッセージを作成します。作成が終わったら、右にあるSend test message
ボタンを押します。
次のような画面が出るとAdd an FCM registration token
へ上でコピーしたFCM Tokenを入力して、+
ボタンを押します。
その後、Test
ボタンを押してテストメッセージを送信します。
そしたら下記のようにメッセージが受信できることが確認できます。
完了
React Nativeプロジェクトでreact-native-firebaseライブラリを使ってFCMメッセージを受ける方法について見てみました。Javascriptから取得したFCM Tokenをサーバに保存して、そのTokenを使ってメッセージを送信することでPush notificationを実装することができます。
私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!
アプリ広報
Deku
が開発したアプリを使ってみてください。Deku
が開発したアプリはFlutterで開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。