2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

HTTP POSTで特定のAndroid移動機にFirebase Notificationを送る

Last updated at Posted at 2016-11-22

前提

FirebaseのProject Setupが完了していて,Notificationを受けるAPK(Client App)にFirebaseの何かの機能(Analyticsとか)がすでに組み込まれていること
(google-services.jsonをapp/にCopyしたりするところまでは完了していること)

↓ このPostでAndroid AppにFirebase Analytics組み込むまでをやってます.
http://qiita.com/fezrestia/items/c303143a20b049909ca4

やること

ざっくり,
 1. Client AppにFCM(Firebase Cloud Messaging)機能を追加
 2. Client Appを特定するためのInstance ID Tokenを取得
 3. サーバ等からHTTP POST Requestを発行
の3 StepでOK.

Step1 Client AppにFCM機能を追加

Ref : https://firebase.google.com/docs/cloud-messaging/android/client

↓ App Levelのbuild.gradleにfirebase-messagingのLibを追加.

app/build.gradle
dependencies {
    compile 'com.google.firebase:firebase-messaging:9.6.1'
}

↓ FirebaseのEventを受けるためのServiceをAndroid Manifestに追加.

app/src/main/AndroidManifest.xml
<!-- Firebase -->
<service
    android:name=".firebase.FcmMessagingService"
>
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

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

↓ Serviceの実装.javaも追加.

app/src/main/java/.../firebase/FcmMessagingService.java
public class FcmMessagingService extends FirebaseMessagingService {
    // AppがBackgroundの状態でNotification出すだけならカラ実装でOKのはず.
    // ForegroundでNotificationを受けるときはonMessageReceived()とかOverrideする.
}
app/src/main/java/.../firebase/FcmInstanceIdService.java
public class FcmInstanceIdService extends FirebaseInstanceIdService {
    // TODO: Step2で実装追加
}

これでClient AppへのFCM機能組み込みは完了.

Step2 Client Appを特定するためのInstance ID Tokenを取得

Ref : https://firebase.google.com/docs/cloud-messaging/android/client

Stpe1で追加した,FirebaseInstanceIdService(FirebaseInstanceId)を使ってInstance ID Tokenを取得する.
初めてAppを起動した時に,自動的にTokenが払い出されるのでそれをLog出力とかで取得する.

app/src/main/java/.../firebase/FcmInstanceIdService.java
public class FcmInstanceIdService extends FirebaseInstanceIdService {
    @Override
    public void onTokenRefresh() {
        // Get updated Instance ID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d("Instance ID Token", "onTokenRefresh() : Token=" + refreshedToken);

        //TODO: Send Instance ID Token to server.
    }
}

変更時にしかonTokenRefresh()はCallbackされないので,Install後の初回起動時にしかCallbackされない.
適当なActivityのonResume()とかで
FirebaseInstanceId.getInstance().getToken();
とかして取り出したほうが楽かも.

TokenのReferenceによると,AppのInstallやClear Data時にTokenがRefreshされるとのこと.
本番運用のためには,Token更新後にServerとかに送って保持する仕組みが必要.

Ref : https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceIdService.html#onTokenRefresh()

Step3 サーバ等からHTTP POST Requestを発行

Ref : https://firebase.google.com/docs/cloud-messaging/server

送信先の種類によって実装が色々なパターンになる模様.
ここでは特定の1つの端末に向けてNotificationを発行する.

Firebase Cloud Messaging Token取得

Firebase ConsoleからFCM Tokenを取得.
Server Keyでも動作するけど,Obsoletedになっているようなので使わないほうが良さそう.
fcm_token_on_firebase_console.png

HTTP POST Request発行

サーバ等から,
https://fcm.googleapis.com/fcm/send
に向けてHTTP POSTを発行する.

今回はRailsサーバから発行してみた.

server.rb
require 'net/https'

# HTTP Request
uri = URI.parse("https://fcm.googleapis.com/fcm/send")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.path)

# Header
request["Content-Type"] = "application/json"
request["Authorization"] = "key=<Firebase Consoleから取得したFCM Token>}"

# Body
payload = "{
    \"notification\": {
        \"title\": \"HELLO WORLD !\",
        \"text\": \"1st notification test\"
    },
    \"to\": \"<Step2で取得したClient AppのInstance ID Token>\"
}"
request.body = payload

# Submit
response = http.request(request)

これでAndroid移動機上にNotificationがでるはず.

まとめ

Firebase ConsoleからNotificationを送るよりも,Client App側への仕込みが必要だったり,Instance ID Tokenをサーバ側(HTTP POST送信元)で保持する必要があったり,いくらか面倒.
今回はサーバ側で定期実行しているTaskから移動機に通知を出したかったので調べてみました.

Firebase Cloud Messaging自体,送信先をTopicでカテゴライズできたりとか,いろいろ機能が豊富なので,まだまだいろんなことできそう.

///---

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?