Firebase Cloud Messaging サーバーについて

サーバー側の Firebase Cloud Messaging は、次の 2 つのコンポーネントで構成されます。

  • Google 提供の FCM サーバー
  • アプリサーバーやその他の信頼できる環境Cloud Functions for Firebase など)。

アプリサーバーや信頼できるサーバー環境では、FCM サーバーにメッセージ リクエストを送信し、FCM サーバーからメッセージをユーザーの端末で実行されているクライアント アプリに送信します。

クライアント側の実装について詳しくは、お使いのプラットフォームのクライアント ガイド(iOSAndroidChrome)をご覧ください。

信頼できるサーバー環境の役割

Firebase Cloud Messaging を使用するクライアント アプリを作成するには、次の条件を満たすサーバー環境をあらかじめ用意する必要があります。

  • クライアントと通信できること。
  • 適切にフォーマットされたメッセージ リクエストを FCM サーバーに送信できること。
  • リクエストを処理し、指数バックオフを使用して再送信できること。
  • サーバーキーとクライアント登録トークンを安全に保存できること。注: サーバーキーはどのクライアント コードにも決して含めないでください。
  • XMPP の場合、送信する各メッセージを一意に識別するメッセージ ID をアプリサーバーで生成できること(FCM HTTP 接続サーバーはメッセージ ID を生成し、それらをレスポンスで返します)。XMPP メッセージ ID は送信者 ID ごとに一意のものにする必要があります。

FCM サーバーと対話する方法には Admin SDK を使う方法、そして未加工の HTTP サーバー プロトコルや XMPP サーバー プロトコルを使う方法があり、どちらを採用するか決定する必要があります。クライアント アプリケーションからのアップストリーム メッセージングを使用する場合は、XMPP を使用する必要があります。詳しくは FCM サーバー プロトコルをご覧ください。

FCM サーバー プロトコル

現在、FCM では HTTPXMPP の 2 つのサーバー プロトコルが用意されています。アプリサーバーでこれらを別々に使用することも、一緒に使用することもできます。XMPP メッセージングは、次の点で HTTP メッセージングとは異なります。

  • アップストリームまたはダウンストリーム メッセージ
    • HTTP: ダウンストリームのみ、クラウドから端末。
    • XMPP: アップストリームとダウンストリーム(端末からクラウド、クラウドから端末)。
  • メッセージング(同期または非同期)
    • HTTP: 同期。アプリサーバーは、HTTP POST リクエストとしてメッセージを送信し、レスポンスを待機します。このメカニズムは同期的であり、送信者はレスポンスを受信するまで別のメッセージを送信できません。
    • XMPP: 非同期。アプリサーバーはすべての端末との間で、永続的な XMPP 接続を使用して最大の回線速度でメッセージを送受信します。XMPP 接続サーバーは、受信確認または失敗通知(特別な ACK および NACK JSON エンコード XMPP メッセージの形式)を非同期で送信します。
  • JSON
    • HTTP: HTTP POST として送信された JSON メッセージ。
    • XMPP: XMPP メッセージにカプセル化された JSON メッセージ。
  • 書式なしテキスト
    • HTTP: HTTP POST として送信された書式なしテキスト メッセージ。
    • XMPP: サポートされていません。
  • 複数の登録トークンに送信されるマルチキャスト ダウンストリーム
    • HTTP: JSON メッセージ形式でサポートされます。
    • XMPP: サポートされていません。

HTTP サーバー プロトコルの実装

ここでは、FCM HTTP サーバー プロトコルを使用して、メッセージ リクエストを認証、作成する方法について説明します。すべてのメッセージ パラメータとそれらをサポートするプロトコルの一覧については、サーバー リファレンスをご覧ください。

認証

メッセージを送信するために、アプリサーバーは POST リクエストを発行します。次に例を示します。

https://fcm.googleapis.com/fcm/send

メッセージ リクエストは、HTTP ヘッダーと HTTP 本文の 2 つの部分で構成されます。

HTTP ヘッダーには次のヘッダーが含まれている必要があります。

  • Authorization: key=YOUR_SERVER_KEY
    これがサーバーキーであることを確認してください。この値は、Firebase コンソールの [設定] ペインの [クラウド メッセージング] タブで確認できます。Android、iOS、およびブラウザのキーは、FCM によって拒否されます。
  • Content-Type: application/json(JSON の場合) application/x-www-form-urlencoded;charset=UTF-8(書式なしテキストの場合)
    Content-Type が省略された場合、形式は書式なしテキストと見なされます。

次に例を示します。

Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "data" : {
    ...
  },
}

HTTP 本文のコンテンツは、使用している形式が JSON なのか書式なしテキストなのかで異なります。 JSON または書式なしテキスト メッセージに含めることのできる全パラメータの一覧については、サーバー リファレンスをご覧ください。

サーバーキーの有効性の確認

メッセージを送信するときに、認証エラーが起こった場合は、サーバーキーの有効性を確認してください。たとえば Android では次のコマンドを実行します。

# api_key=YOUR_SERVER_KEY

# curl --header "Authorization: key=$api_key" \
       --header Content-Type:"application/json" \
       https://fcm.googleapis.com/fcm/send \
       -d "{\"registration_ids\":[\"ABC\"]}"

401 HTTP ステータス コードが返された場合、サーバーキーは有効ではありません。それ以外の場合は次のように表示されます。

{"multicast_id":6782339717028231855,"success":0,"failure":1,
"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}

登録トークンの有効性を確認する場合は、「ABC」を登録トークンに置き換えます。

リクエストの形式

このセクションでは、JSON と書式なしテキストの両方のリクエストを作成する方法を示します。リクエストに含めることのできるフィールドの完全な一覧については、サーバー リファレンスをご覧ください。

送信後同期

JSON を使用した最小限のリクエスト(パラメータを持たず受信者が 1 人だけのメッセージ)例は、次のとおりです。

{ "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..." }

書式なしテキストを使用した場合は、上記の例が次のようになります。

registration_id=42

ペイロードを含むメッセージ — 通知メッセージ

通知メッセージの例は次のとおりです。

{ "notification": {
    "title": "Portugal vs. Denmark",
    "body": "5 to 1"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

ペイロードを含むメッセージ - データ メッセージ

データ ペイロードを含むメッセージの例は次のとおりです。

{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

次の例では、メッセージにすべてのオプション フィールドが設定されています。

{ "collapse_key": "score_update",
  "time_to_live": 108,
  "data": {
    "score": "4x8",
    "time": "15:16.2342"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

書式なしテキスト形式を使用した場合は、上記の例が次のようになります。

collapse_key=score_update&time_to_live=108&data.score=4x8&data.time=15:16.2342&registration_id=42
  

レスポンスの形式

メッセージを送信しようとした場合、起こり得る結果は次の 2 通りです。

  • メッセージが正しく処理されます。HTTP レスポンスにはステータス コード 200 が含まれ、本文にはメッセージのステータスに関する詳細が記されます。
  • FCM サーバーがリクエストを拒否します。HTTP レスポンスには 200 以外のステータス コード(400、401、5xx など)が含まれます。

JSON リクエストが成功すると(HTTP ステータス コード 200)、返される JSON オブジェクトには、ダウンストリーム HTTP メッセージ レスポンスの本文が含まれます。Google サポートでメッセージのトラブルシューティングを行う必要がある場合に備え、すべてのメッセージのメッセージ ID 値を記録してください。

failurecanonical_ids の値が 0 である場合は、レスポンスの残りを解析する必要はありません。それ以外の場合、結果フィールドを順に見ていき、リスト内のオブジェクトごとに次の操作を行うことをおすすめします。

  • message_id が設定されている場合、registration_id を確認します。
    • registration_id が設定されている場合、元の ID をサーバー データベース内の新しい値(正規 ID)に置き換えます。元の ID は結果に含まれていないので、リクエストで渡された registration_ids のリストから同じインデックスを使って取得する必要があります。
  • それ以外の場合、error の値を取得します。
    • 値が Unavailable である場合、別のリクエストでもう一度メッセージを送信してみることができます。
    • 値が NotRegistered である場合、アプリケーションが端末からアンインストールされたか、クライアント アプリがメッセージを受信するように設定されていません。この場合は、サーバー データベースから登録 ID を削除してください。
    • 上記以外の場合、リクエストで渡された登録トークンになんらかの問題があります。これは、サーバー データベースから登録を削除することも必要になる回復不能なエラーである可能性があります。すべてのエラー値については、ダウンストリーム メッセージ エラー レスポンス コードをご覧ください。

書式なしテキスト リクエストが成功した場合(HTTP ステータス コード 200)、レスポンスの本文には、Key-Value ペア形式の行が 1~2 行含まれます。1 行目は必ず存在し、その内容は id=ID of sent message または Error=GCM error code になります。2 行目がある場合、registration_id=canonical ID という形式になります。2 行目はオプションで、1 行目がエラーでない場合にのみ送信されます。書式なしテキスト レスポンスの処理は、JSON レスポンスの処理と同様の方法で行うことをおすすめします。

  • 1 行目が id で始まっている場合は、2 行目を調べます。
    • 2 行目が registration_id で始まっている場合は値を取得し、サーバー データベース内の登録トークンをこの値に置き換えます。
  • それ以外の場合、Error の値を取得します。
    • 値が NotRegistered の場合、サーバー データベースから登録トークンを削除します。
    • それ以外の場合は、回復不能なエラーが存在する可能性があります(: 書式なしテキスト リクエストはエラーコードとして Unavailable を返さず、代わりに HTTP ステータス コード 500 を返します)。

レスポンス例

このセクションでは、正常に処理されたメッセージを記したレスポンスの例をいくつか示します。これらのレスポンスの基となるリクエストについては、リクエストの形式をご覧ください。

次の単純な例では、レスポンスに正規 ID を含まず 1 人の受信者に正しく送信された JSON メッセージを示します。

{ "multicast_id": 108,
  "success": 1,
  "failure": 0,
  "canonical_ids": 0,
  "results": [
    { "message_id": "1:08" }
  ]
}

リクエストの形式が書式なしテキストだった場合は次のようになります。

id=1:08

次に示すのは、6 人の受信者(各 ID は、4、8、15、16、23、42)に対する JSON メッセージの結果の例です。ここでは 3 つのメッセージが正しく処理され、そのうち 1 つは正規登録トークンが返され、残りの 3 つはエラーが返されています。

{ "multicast_id": 216,
  "success": 3,
  "failure": 3,
  "canonical_ids": 1,
  "results": [
    { "message_id": "1:0408" },
    { "error": "Unavailable" },
    { "error": "InvalidRegistration" },
    { "message_id": "1:1516" },
    { "message_id": "1:2342", "registration_id": "32" },
    { "error": "NotRegistered"}
  ]
}

上記の例は次のような意味になります。

  • 1 番目のメッセージ: 成功、不要。
  • 2 番目のメッセージ: (登録トークン 8 に)再送信する必要あり。
  • 3 番目のメッセージ: 回復不能なエラーあり(値がデータベース内で破損した可能性あり)。
  • 4 番目のメッセージ: 成功、必要なものなし。
  • 5 番目のメッセージ: 成功だが、登録トークンを(23 から 32 に)サーバー データベース内で更新する必要あり。
  • 6 番目のメッセージ: アプリケーションが端末からアンインストールされたので、登録トークン(42)をサーバー データベースから削除する必要あり。

上記の 3 番目のメッセージだけが書式なしテキスト形式を使用して送信された場合は、次のようになります。

Error=InvalidRegistration

上記の 5 番目のメッセージも書式なしテキスト形式を使用して送信された場合は、次のようになります。

id=1:2342
registration_id=32

XMPP サーバー プロトコルの実装

XMPP では、FCM サーバーへの永続的で非同期的な双方向接続を維持できます。この接続は、FCM に接続したユーザー端末とアプリサーバーとの間でメッセージを送受信するために使用できます。

XMPP と並行して、HTTP リクエスト メカニズムを使って Firebase Cloud Messaging サーバーにメッセージを送信することができます。XMPP のメリットには次のものがあります。

  • XMPP の非同期的な特質上、少ないリソースで多数のメッセージを送信できます。
  • 通信は双方向であり、アプリサーバーから端末にメッセージを送信できるだけでなく、端末からもアプリサーバーにメッセージを送信できます。
  • 端末は、受信に使用される接続と同じものを使用してメッセージを送信できるので、バッテリー持続時間が延びます。

すべてのメッセージ パラメータとそれらをサポートするプロトコルの一覧については、サーバー リファレンスをご覧ください。

接続の確立

長時間継続する FCM への接続の管理には、ほとんどの XMPP ライブラリが利用できます。XMPP エンドポイントは fcm-xmpp.googleapis.com:5235 で実行されます。本番環境以外のユーザーを対象に機能をテストするときは、本番前サーバーである fcm-xmpp.googleapis.com:5236 に接続する必要があります。使用するポートの違いにご注意ください。

本番前環境(最新の FCM ビルドが動作している小規模な環境)で定期的にテストを行うと、テストコードから実際のユーザーを切り離す上で役立ちます。テスト メッセージを本番環境ユーザーに送信したり、テスト接続経由で本番環境トラフィックからアップストリーム メッセージを送信したりするリスクを回避するため、fcm-xmpp.googleapis.com:5236 に接続するテスト端末とテストコードでは、本番環境とは別の FCM 送信者 ID を使用してください。

接続には、次の 2 つの重要な要件があります。

  • Transport Layer Security(TLS)接続を開始する必要があります。現在 FCM では、STARTTLS 拡張機能はサポートされていません。
  • FCM では SASL PLAIN 認証メカニズムが必要です。認証には <your_FCM_Sender_Id>@gcm.googleapis.com(FCM 送信者 ID)と、パスワードとしてサーバーキーを使用します。これらの値は、Firebase コンソールの [設定] ペインの [クラウド メッセージング] タブで確認できます。

いずれかの時点で接続が失敗した場合は、すぐに再接続してください。 認証後に切断された場合は、バックオフする必要はありません。

FCM は送信者 ID 1 つあたり 1,000 件の同時接続を許可します。

認証

次のスニペットは、認証を行う方法を示しています。

クライアント

<stream:stream to="gcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

サーバー

<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-OAUTH2</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

クライアント

<auth mechanism="PLAIN"
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>

サーバー

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

クライアント

<stream:stream to="gcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

サーバー

<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

クライアント

<iq type="set">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"></bind>
</iq>

サーバー

<iq type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>SENDER_ID@gcm.googleapis.com/RESOURCE</jid>
  </bind>
</iq>

注: FCM はメッセージのルーティング中に、バインドされたリソースを使用しません。

ダウンストリーム メッセージ

XMPP 接続が確立されると、FCM とアプリサーバーは、通常の XMPP <message> スタンザを使用して、JSON エンコード メッセージを相互に送信します。<message> の本文は次のようにする必要があります。

<gcm xmlns:google:mobile:data>
    JSON payload
</gcm>

通常の FCM メッセージの JSON ペイロードは、FCM HTTP エンドポイントが使用するものに類似していますが、以下の点が異なります。

  • 複数の受信者をサポートしていません。
  • toregistration_ids の代わりに使用されます。
  • FCM は、必須フィールド message_id を追加します。この ID によって、XMPP 接続でのメッセージが一意に識別されます。FCM からの ACK または NACK は message_id を使用して、アプリサーバーから FCM に送られたメッセージを識別します。したがって、この message_id が(送信者 ID ごとに)一意で、しかも常に存在していることが重要です。

通常の FCM メッセージに加え、JSON オブジェクトの message_type フィールドで示される制御メッセージが送信されます。値は「ack」、「nack」、「control」のいずれかになります(下の形式を参照)。不明な message_type を含む FCM メッセージはいずれもアプリサーバーで無視できます。

アプリサーバーは、FCM から受信する端末へのメッセージごとに、ACK メッセージを送信する必要があります。NACK メッセージは一切送信する必要がありません。メッセージに対して ACK を送信しないと、そのメッセージは、先に期限切れにならない限り、新しい XMPP 接続が次回確立されたときに FCM から再送信されます。

FCM はさらに、サーバーから端末へのメッセージごとに、ACK または NACK を送信します。どちらも受信しないときは、オペレーション中に TCP 接続が閉じられたことを意味し、サーバーはメッセージを再送信する必要があります。詳細については、フロー制御をご覧ください。

すべてのメッセージ パラメータと、各パラメータをサポートする接続サーバーの一覧については、サーバー リファレンスをご覧ください。

リクエストの形式

送信後同期

次に、送信後同期メッセージの単純な XMPP スタンザを示します。

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
  }
  </gcm>
</message>

ペイロードを含むメッセージ — 通知メッセージ

次に、通知メッセージの XMPP スタンザを示します。

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
     "notification": {
        "title": "Portugal vs. Denmark”,
        "body”: "5 to 1”
      },
      "time_to_live":"600"
}

  }
  </gcm>
</message>

ペイロードを含むメッセージ - データ メッセージ

次に、アプリサーバーから FCM への JSON メッセージを含む XMPP スタンザを示します。

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
      "message_id":"m-1366082849205" // new required field
      "data":
      {
          "hello":"world",
      }
      "time_to_live":"600",
      "delivery_receipt_requested": true/false
  }
  </gcm>
</message>

レスポンスの形式

FCM レスポンスが取り得る形式には 3 つあります。最初の形式は通常の「ack」メッセージです。ただし、レスポンスにエラーが含まれる場合、メッセージは下記のように 2 つの異なる形式になります。

ACK メッセージ

次に、FCM からアプリサーバーへの ACK または NACK メッセージを含む XMPP スタンザを示します。

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

NACK メッセージ

NACK エラーは、message_type ステータス メッセージが「nack」である通常の XMPP メッセージです。NACK メッセージには次の要素が含まれます。

  • NACK エラーコード
  • NACK エラーの説明

次に例を示します。

不正な登録:

<message>
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"SomeInvalidRegistrationId",
    "error":"BAD_REGISTRATION",
    "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId"
  }
  </gcm>
</message>

無効な JSON:

<message>
 <gcm xmlns="google:mobile:data">
 {
   "message_type":"nack",
   "message_id":"msgId1",
   "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "error":"INVALID_JSON",
   "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc"
 }
 </gcm>
</message>

デバイス メッセージ レートの超過:

<message id="...">
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"REGID",
    "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
    "error_description":"Downstream message rate exceeded for this registration id"
  }
  </gcm>
</message>

すべての NACK エラーコードの一覧については、サーバー リファレンスをご覧ください。特に指示のない限り、NACK が返されたメッセージは再試行しないでください。予期しない NACK エラーコードは INTERNAL_SERVER_ERROR と同じように扱ってください。

スタンザエラー

特定の場合には、スタンザエラーが発生することもあります。 スタンザエラーには次の要素が含まれます。

  • スタンザエラー コード
  • スタンザエラーの説明(フリーテキスト)

次に例を示します。

<message id="3" type="error" to="123456789@gcm.googleapis.com/ABC">
  <gcm xmlns="google:mobile:data">
     {"random": "text"}
  </gcm>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
    </text>
  </error>
</message>

制御メッセージ

FCM では、負荷分散を行うために定期的に接続を閉じる必要があります。接続を閉じる前に、FCM は CONNECTION_DRAINING メッセージを送信して、接続がドレインされていて間もなく閉じられることを伝えます。「ドレイン」とは、接続に新たに入ってくるメッセージのフローを遮断し、すでにパイプラインに存在するものはすべてそのまま処理されるようにすることです。CONNECTION_DRAINING メッセージを受信した場合は、必要に応じて新しい接続を開きながら、別の FCM 接続へのメッセージの送信をすぐに開始してください。ただし、元の接続を開いたままにして、その接続で着信する可能性のあるメッセージを受信(および ACK で応答)し続ける必要があります。FCM は、準備が整うと接続閉鎖の開始を処理します。

CONNECTION_DRAINING メッセージは次のようになります。

<message>
  <data:gcm xmlns:data="google:mobile:data">
  {
    "message_type":"control"
    "control_type":"CONNECTION_DRAINING"
  }
  </data:gcm>
</message>

現在サポートされている control_type は、CONNECTION_DRAINING のみです。

配信確認を受信する

Android と Chrome のクライアント アプリの場合、FCM から送信されたメッセージを受信したことを端末が確認したときに、(FCM からアプリサーバーに送信される)配信確認を受け取ることができます。

この機能を有効にするには、アプリサーバーから FCM に送信されるメッセージにフィールド delivery_receipt_requested が含まれている必要があります。このフィールドが true に設定されている場合、特定のメッセージを受信したことを端末が確認したときに、FCM は配信確認を送信します。

次に、"delivery_receipt_requested"true に設定された JSON メッセージを含む XMPP スタンザを示します。

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",
      "message_id":"m-1366082849205"
      "data":
      {
          "hello":"world",
      }
      "time_to_live":"600",
      "delivery_receipt_requested": true
  }
  </gcm>
</message>

FCM が送信したメッセージを端末が受信したことをアプリサーバーに知らせるために FCM から送信される配信確認の例は、次のとおりです。

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "category":"com.example.yourapp", // to know which app sent it
      "data":
      {
         “message_status":"MESSAGE_SENT_TO_DEVICE",
         “original_message_id”:”m-1366082849205”
         “device_registration_id”: “REGISTRATION_ID”
      },
      "message_id":"dr2:m-1366082849205",
      "message_type":"receipt",
      "from":"gcm.googleapis.com"
  }
  </gcm>
</message>

次の点にご注意ください。

  • "message_type""receipt" に設定されています。
  • "message_status""MESSAGE_SENT_TO_DEVICE" に設定され、端末がメッセージを受信したことを示します。この場合、"message_status" はフィールドではなく、データ ペイロードの一部です。
  • 確認メッセージの ID は元のメッセージ ID で構成されますが、dr2: 接頭辞が付きます。アプリサーバーは、この ID(この例では dr2:m-1366082849205)で ACK を送信する必要があります。
  • 元のメッセージ ID、端末の登録トークン、ステータスは、"data" フィールドの中に含まれます。
  • FCM と端末間の接続が不安定な場合、Firebase Cloud Messaging は複数の重複した配信確認を送信することがあります。このような重複した配信確認は無視してかまいません。

フロー制御

FCM に送信されたすべてのメッセージは、ACK または NACK のレスポンスを受信します。どちらのレスポンスも受信していないメッセージは保留中と見なされます。保留中のメッセージ数が 100 に達すると、アプリサーバーは、図 1 に示したように、新しいメッセージの送信を停止し、既存の保留中のメッセージを FCM が確認するまで待機する必要があります。

図 1. メッセージと ACK のフロー

反対に、確認されていないメッセージ数が非常に多い場合、アプリサーバーに負荷をかけすぎないように、FCM はメッセージの送信を停止します。したがって、アプリサーバーは着信メッセージの一定のフローを維持するため、FCM 経由でクライアント アプリケーションから受信したアップストリーム メッセージにできるだけ早く「ACK」で応答する必要があります。上記の保留中のメッセージ数の制限は、これらの ACK には適用されません。保留中のメッセージ数が 100 に達した場合でも、アプリサーバーは、新しいアップストリーム メッセージの配信が妨げられないように、FCM から受信したメッセージに対して ACK を送信し続ける必要があります。

ACK は、1 つの接続のコンテキスト内でのみ有効です。メッセージに対して ACK で応答する前に接続が閉じた場合、アプリサーバーは、FCM がアップストリーム メッセージを再送信するまで待機してから、再度 ACK を送信する必要があります。同様に、接続が閉じられる前に FCM から ACK または NACK を受信しなかった保留中のすべてのメッセージを再び送信する必要があります。

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。