Android8以降だとreact-native-firebase/messagingのプッシュ通知がサイレントになる
はじめに
スマホアプリ開発をしているとプッシュ通知は避けて通れない機能です。
特にReactNative
のようにクロスプラットフォーム開発をしている場合は、iOS
とAndroid
のように異なるOS
のプッシュ通知の機構をラップしたライブラリを使うことがほとんどだと思います。
プッシュ通知に限らない話なのですが、ReactNative
で開発する場合、私はreact-native-firebase
を使っています。
認証機能やストレージ、DBなどバックエンドの主要な機能がほとんどまかなえてしまうためです。
話をプッシュ通知に戻すと、react-native-firebase
ではreact-native-firebase/messaging
を使って通知関係の処理を行います。
しかし、Android
のOS
のバージョンによっては通知音やバイブレーションが鳴らない所謂 「サイレント通知」 になります。
今回はreact-native-firebase/messaging
を使ってプッシュ通知を受信する場合にAndroid8
以降で発生するサイレント通知の対処法を紹介します。
前提条件
@react-native-firebase/app@8.3.1
@react-native-firebase/messaging@7.7.2
今回はサイレント通知に関する対処法の紹介のため、プッシュ通知の受信に関する設定や基本的なイベント処理については割愛します。
※これはまた別記事に起こす予定なので、そちらで解説できればと思います。
Android 8
だとサイレント通知になる?
なぜサイレント通知となる場合、おそらくAndroid8
以降だと思います。
これはAndroid 8(Oreo)
から追加された 「通知チャンネル」 というものによるためです。
以下引用です。
Android 8.0(API レベル 26)以降、通知はすべてチャネルに割り当てる必要があります。チャネルごとに、そのチャネルのすべての通知に適用される表示と音声の動作を設定することができます。
従って、プッシュ通知で音やポップアップを表示する場合は通知チャンネルを明示的に指定しなければなりません。
react-native-firebase/messaging
のチュートリアルに倣って一連の処理をコーディングした段階では、この通知チャンネルの指定が出来ていない状態のため、Android8
以降ではサイレント通知となります。
v5
系まではソース上で指定ができた
react-native-firebase
の現在の最新はv6
系です。
この通知チャンネルの指定ですが、v5
系まではnotifications()
というモジュールが用意されていたため、JS
上で指定することができました。
しかし、v6
系では廃止されたらしく、指定には少し工夫(ネイティブコードで記載)が必要です。
対処方法
上記にもある通りネイティブコードの修正が必要になります。
android/app/src/main/java/com/{appName}
にあるMainActivity.java
に下記のようにcreateNotificationChannel
メソッドを追加しonCreate()
で呼び出すようにしましょう。
import
を追加する必要もあるので、忘れないようにしましょう。
package hogehoge;
import android.os.Bundle;
import android.os.Build; // 追加
import android.app.NotificationChannel; // 追加
import android.app.NotificationManager; // 追加
import com.facebook.react.ReactActivity;
public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// チャンネル作成処理を実行
createNotificationChannel();
}
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "appname";
}
/**
* 通知チャンネルの作成
*/
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 通知ID
String id = "notification";
// チャンネル名
CharSequence name = "お知らせ";
// チャンネル説明
String description = "アプリからのお知らせ情報を通知します。";
// 重要度
int importance = NotificationManager.IMPORTANCE_HIGH;
//チャンネルインスタンスを作成
NotificationChannel channel = new NotificationChannel(id, name, importance);
// 説明を設定
channel.setDescription(description);
// チャンネルマネージャインスタンスを作成しチャンネルをセット
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
}
こうすることでアプリ起動時に自動的にnotification
というID
で通知チャンネルが作成されます。
通知発行側はこのID
を指定して通知を出す形になります。
さらにここで作成した通知チャンネルをデフォルトとするための設定を行います。
プロジェクトのルートにfirebase.json
を作成し、以下のようにします。
{
"react-native": {
"messaging_android_notification_channel_id": "notification"
}
}
これでAndroid8
でも通知音やバイブレーション、ポップアップが表示されるようになります。
まとめ
今回はreact-native-firebase/messaging
を使っている場合に、Android8
以降で発生するサイレント通知への対処法をご紹介しました。
今回は、ライブラリのバージョンが上がって特定の機能が使えなくなるというパターンに加えて、OS
側もバージョンアップで今まで動作していたコードが機能しなくなるという破壊的な変更が重なったため、ネイティブコードレベルで対応が必要となったケースだと思います。
firebase
が絡んでくるような機能は、大概がアプリのコア機能だと思うので早め早めに対応していくのが吉かなと思います。
Discussion