ReactNative+ExpoでAndroid端末へプッシュ通知を送る その①〜Expo プッシュトークンの取得〜
Expoを使用して開発するReactNativeアプリから各端末へプッシュ通知を送る仕組みを入れたいと思います。
私の端末はAndroidなのでまずはAndroid端末へ送れるようにしたのですが、途中試行錯誤したのでやり方を載せたいと思います。
※Android向けの説明になりますが、iOSの方も途中までは参考にしていただけます。 iOSだともう少し手間なくできるかも?です。(未検証)
- バージョン
- 準備
- 開発手順
- Push通知の手順
- プッシュトークンの取得
- Error: Couldn't get GCM token for device の対応
- Firebaseプロジェクトの作成
- androidパッケージの決定
- FirebaseへAndroidアプリの追加
- google-services.jsonのダウンロードと配置
- FCMサーバーキーの取得
- ExpoへFCMサーバーキーの登録
- プッシュ通知のテスト
- まとめ
バージョン
[アプリケーション]
・create-react-native-app:2.0.2
・Expo CLI:2.4.0
・React Native SDK:31.0.0
後は今回の記事に関係しないので割愛。
[端末]
準備
プッシュ通知の確認は実機ベースが必須なので、GooglePlayよりExpoアプリをインストールしておいてください。
開発手順
プライベートなリポジトリで開発しているためソースは断片的にしか公開できませんので、簡単に開発手順をまとめます。
Expo CLIを使ってプロジェクト作れる方は飛ばしてもらってもOKです。
create-react-native-app インストール
npm install -g create-react-native-app
私と同じバージョンで始める場合は、
npm install -g create-react-native-app@2.0.2
Expo CLI インストール
npm install -g expo-cli
私と同じバージョンで始める場合は、
npm install -g expo-cli@2.4.0
React Nativeプロジェクト作成
create-react-native-app [your-project-name]
これでプロジェクトが作成されます。
アプリ起動
expo start
npm start
ではなくexpoコマンドで起動します。
起動すると、localhost:19002でブラウザが自動で起動します。
↓こんな感じ
ここに表示されるQRコードをスマホ端末でExpoアプリを使ってスキャンすると、スマホ上にアプリがロードされます。(ここまでがアプリの初期セットアップ)
Push通知の手順
公式ドキュメントの内容をまとめると、
- Expoからプッシュトークンを取得する
- プッシュトークンを自分のサーバで保管する(ユーザ情報と紐付けておく)
- プッシュ通知を行うアクションが発生した際に、自分のサーバからExpoのプッシュ通知用のAPIをコールする(この際にプッシュトークンを使う)
- Expoが各端末へプッシュ通知を送る(OSのハンドリングはExpo側で行う)
- フォアグラウンドにあると通知が表示されないので、表示するようにハンドリングする(iOS用?)
読む限り、1でプッシュトークンが取得できれば、後はAPIを呼び出すだけのような気がします。
プッシュトークンの取得
先ほどの公式サイトにあるサンプルコードを真似てみます。
下記のコード(関数)をApp.jsに追加します。念のためtry-catchします。
import { Permissions, Notifications } from 'expo'; 〜〜 async function registerForPushNotificationsAsync() { try { const { status: existingStatus } = await Permissions.getAsync( Permissions.NOTIFICATIONS ); let finalStatus = existingStatus; // only ask if permissions have not already been determined, because // iOS won't necessarily prompt the user a second time. if (existingStatus !== 'granted') { // Android remote notification permissions are granted during the app // install, so this will only ask on iOS const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS); finalStatus = status; } // Stop here if the user did not grant permissions if (finalStatus !== 'granted') { return; } // Get the token that uniquely identifies this device let token = await Notifications.getExpoPushTokenAsync(); console.log(token); } catch (e) { console.error(e); } }
App.jsの初期処理で呼び出すようにします。
export default class App extends React.Component { componentDidMount() { registerForPushNotificationsAsync(); } render() { ... } }
ここまでは下記のブログを参考にさせていただいたので、これで動くと思っていました。
ですが!!
これでアプリを起動すると、、
Error: Couldn't get GCM token for device
なにやらエラーになりました。
どうもGCM(Google Cloud Messaging)が廃止され、FCM(Firebase Clound Messaging)へ移行しろっていう流れがあるらしいので、それに関連したエラーっぽいです。
Error: Couldn't get GCM token for device の対応
色々調べたのですが、公式ドキュメントに下記の記載があるのを見落としていました。
要約すると、
「FCMのサーバーキーをExpoに送ってくれないとExpoからプッシュ通知できなくなったんだ。こっちのページにFirebaseプロジェクトの作り方を書いたからそれを見てFCMサーバーキーの取得してExpoに送ってくれ。」
みたいなことを言ってます。
こちらに手順が書いてあるので、その通り進めていくことにします。
Firebaseプロジェクトの作成
Firebaseプロジェクトを作成していない方はFirebaseコンソールからプロジェクトを作成します。
https://console.firebase.google.com/
[+]プロジェクトを追加 を押します。
プロジェクト名を入力、地域/ロケーションを日本/asia-northeast1に変更してプロジェクトを作成します。
androidパッケージの決定
※これは公式ドキュメントには書かれていません。
この後の手順でandroidパッケージが必要になります。
これはアプリの開発元やアプリ名に依存しますので、各自で決定お願いします。
com.[your company].[your app name]
みたいな感じでしょうか。
決定しましたら、app.jsonに下記の記載を追加します。
"android": { "package": "[your android package]" }
既に "android"がある場合は、その中にpackageを追記します。
"android": { "hoge": "fuga", →"package": "[your android package]" }
FirebaseへAndroidアプリの追加
Firebaseコンソール画面で[Android アプリに Firebase を追加] をクリックするとアプリの登録画面が開きます。
ここに先ほど決定したandroidパッケージを入力して、[アプリを登録]します。
google-services.jsonのダウンロードと配置
アプリ登録が終わるとgoogle-services.json をダウンロードできるようになるのでダウンロードします。
ダウンロードしたgoogle-services.jsonはプロジェクト直下に配置します。
/ App.js app.json google-services.json
app.jsonに設定を追記します。
"android": { ...., "googleServicesFile": "./google-services.json" }
あともう少しです。
FCMサーバーキーの取得
Firebaseコンソールで[Project Overview の右の歯車] → [プロジェクトの設定] を押します。
[クラウドメッセージング]タブを開くとサーバーキーが表示されているので、コピーします。
ExpoへFCMサーバーキーの登録
最後にExpoへコピーしたサーバーキーを登録します。expoコマンドを使います。
expo push:android:upload --api-key <your-token-here>
途中でExpoのアカウント登録を要求されるので登録します。 登録後メールでverifyするとアカウント作成されます。
以上で必要な手順は終わりです。
プッシュ通知のテスト
ここまで来ると先ほどアプリ起動で出ていたエラーは出なくなり、以下のようなプッシュトークンがログに出力されると思います。
ExponentPushToken[xxxxxxx]
これをExponentから全てコピーします。
プッシュ通知は本来であればExpoのAPIを使用するのですが、下記のダッシュボード画面からプッシュ通知を送ることができます。
プッシュトークンとタイトルと本文を入力し [Send a notification]をクリックします。
すると、
スマホ側にプッシュ通知が届きました!
まとめ
いかがだったでしょうか?
基本的にはExpoが提供するサンプルコードでプッシュトークンは取得できるのですが、以前は起こらなかったGCMのエラーが出るようになっているので今回記載したようにFirebaseプロジェクトを作成する必要が出てきています。
この後はAWS Lambda経由で実際にExpoのAPIをコールしてみたいと思いますので、また実現できたら書こうと思います。