読者です 読者をやめる 読者になる 読者になる

たけぼーの備忘録

暇を持て余した人間の無意味なブログ

firebaseのNotificationでプッシュ通知をやってみる

プログラミング

こんにちは、たけぼーです。
今回は、googleが無料で提供しているfirebaseのNotificationを使ってみようと奮闘しました。

きっかけは、プッシュ通知とかできたらかっこよくね?という安直なもの。
いやー、苦戦しました。
素人の私がかっこよさだけでやると大変なことになりましたよ。
ですが、今後プッシュ通知は何かと役に立つので、いい経験になったと思います。

今回参考にさせていただきましたサイトはこちら

qiita.com

このページを見れば、利用登録からプッシュ通知の送信まで、一気にわかります。
正直、私が新たに書く必要がない 笑

ですが、ところどころハマったポイントがあったので、そこを書こうと思います。


では、まいりましょう。

まずは、ここに書いてあるようにやっていったのですが、いざやってみますと、エラーで落ちてしまう。
なぜなんだ・・・

エラーをよーく見てみると、なにかしらのパーミッションが足りません、的なエラーが出ました。
google大先生に聞いてみると、どうもAndroidManifestに

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>

を、足さなければならないらしいです。それ先に言ってくれよ・・・

こんなの誰も書いてなかったので、もしかしたらfirebaseと関係ないのかもしれません。
ですから、エラーが出たときだけ試してみてくださいね!

これでエラーもなく通知を受け取れるようになったわけですが、実はこれ、アプリがバックグラウンドにいるときだけなんです。
バックグラウンドならシステムが自動で通知を生成してくれるのですが、アプリが起動しているときにはまたもやエラーが出てしまいます。

これは、firebaseのメッセージを受信するserviceがアプリの中にないからで、公式のガイドにもonMessageReceivedを作成するように書かれています。

ということで、サクッと作成してみます。
もはや実用的かはわかりませんが、とりあえず通知が表示されるようになります。

package ... ;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.NotificationCompat;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Map;

public class NotificationService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());
        builder.setSmallIcon(R.drawable.ic_stat_create);
        builder.setContentTitle(getString(R.string.app_name));
        builder.setContentText(remoteMessage.getNotification().getBody());
        builder.setColor(ContextCompat.getColor(getBaseContext(),R.color.colorPrimary));
        builder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS);
        builder.setAutoCancel(true);
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(contentIntent);

        NotificationManagerCompat manager = NotificationManagerCompat.from(getApplicationContext());
        manager.notify(1, builder.build());
    }
}

Serviceとして認識させるため、AndroidManifest.xmlに追記しました。

<service
      android:name=".NotificationService">
      <intent-filter>
          <action android:name="com.google.firebase.MESSAGING_EVENT"/>
      </intent-filter>
</service>

こちらを参考にさせていただきました。
qiita.com

これで、アプリが起動していてもプッシュを受け取ることができるようになりました。

最後に、システムが自動で通知を生成する場合(アプリがバックグラウンドにいる場合)通知に表示されるアイコンが真っ白になってしまいました。
これは、通知に表示されるアイコンが自動的にアプリのランチャーアイコンになるからです。
要するに、アイコンのシルエットが表示されるので、白いものが表示されるのです。
私はすでに通知用のアイコン(背景を透明にしてあるアイコン)がありますので、それを表示させたい。

こいうことで、システムに通知用アイコンを指定するため、AndroidManifest.xmlに追記しました。

<meta-data 
      android:name="com.google.firebase.messaging.default_notification_icon"
      android:resource="@drawable/ic_stat_create"/>
<meta-data 
      android:name="com.google.firebase.messaging.default_notification_color"
      android:resource="@color/colorPrimary"/>

これで、無事に通知を受け取ることができるようになりました!

ということで今回はここまで。ではまた。