Firebase Summit で発表されたすべての情報をご覧ください。Firebase を使用してアプリ開発を加速し、自信を持ってアプリを実行する方法を紹介しています。詳細
コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

サーバー環境と FCM

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

  • Google が提供するFCM バックエンド
  • Cloud Functions for Firebaseや Google が管理するその他のクラウド環境など、アプリ サーバーまたはサーバー ロジックが実行されるその他の信頼できるサーバー環境

アプリ サーバーまたは信頼できるサーバー環境は、メッセージ リクエストを FCM バックエンドに送信します。FCM バックエンドは、ユーザーのデバイスで実行されているクライアント アプリにメッセージをルーティングします。

信頼できるサーバー環境の要件

アプリ サーバー環境は、次の基準を満たしている必要があります。

  • 適切にフォーマットされたメッセージ リクエストを FCM バックエンドに送信できます。
  • リクエストを処理し、指数バックオフを使用して再送信できます。
  • サーバー認証資格情報とクライアント登録トークンを安全に保管できます。
  • XMPP プロトコル (使用する場合) の場合、サーバーは、送信する各メッセージを一意に識別するためにメッセージ ID を生成できる必要があります (FCM HTTP バックエンドはメッセージ ID を生成し、応答で返します)。 XMPP メッセージ ID は、送信者 ID ごとに一意である必要があります。

サーバーオプションの選択

FCM サーバーと対話する方法を決定する必要があります。Firebase Admin SDKを使用するか、生のプロトコルを使用します。一般的なプログラミング言語をサポートし、認証と承認を処理するための便利な方法があるため、Firebase Admin SDK が推奨される方法です。

FCM サーバーと対話するためのオプションには、次のものがあります。

  • NodeJavaPythonC# 、およびGoをサポートする Firebase Admin SDK。
  • 最新のプロトコル オプションであるFCM HTTP v1 APIは、より安全な承認と柔軟なクロスプラットフォーム メッセージング機能を備えています (Firebase Admin SDK はこのプロトコルに基づいており、固有の利点をすべて提供します)。通常、新しい機能は HTTP v1 API にのみ追加されるため、ほとんどのユース ケースでこの API を使用することをお勧めします。
  • 従来の HTTPプロトコル。新しいプロジェクトでは、レガシー プロトコルの代わりに FCM v1 HTTP API を採用することを強くお勧めします。
  • 従来の XMPPサーバー プロトコル。新しいプロジェクトでは、レガシー プロトコルの代わりに FCM v1 HTTP API を採用することを強くお勧めします。

FCM 用の Firebase Admin SDK

Admin FCM API は、バックエンドでの認証を処理し、メッセージの送信とトピック サブスクリプションの管理を容易にします。 Firebase Admin SDK を使用すると、次のことができます。

  • 個々のデバイスにメッセージを送信する
  • 1 つ以上のトピックに一致するトピックおよび条件ステートメントにメッセージを送信します。
  • デバイスをトピックにサブスクライブおよびサブスクライブ解除する
  • さまざまなターゲット プラットフォームに合わせたメッセージ ペイロードを構築する

Admin Node.js SDK は、デバイス グループにメッセージを送信するためのメソッドを提供します。

Firebase Admin SDK をセットアップするには、「 Firebase Admin SDK をサーバーに追加する」を参照してください。すでに Firebase プロジェクトがある場合は、SDK を追加するから始めます。また、プロジェクトのCloud Messaging 設定ページで Cloud Messagin API を有効にしてください。次に、Firebase Admin SDK がインストールされると、送信リクエストを作成するためのロジックの記述を開始できます。

FCM サーバー プロトコル

現在、FCM は次の raw サーバー プロトコルを提供しています。

アプリ サーバーは、これらのプロトコルを個別に使用することも、組み合わせて使用​​することもできます。 FCM HTTP v1 API は、複数のプラットフォームにメッセージを送信するための最新かつ最も柔軟な API であるため、可能な限り FCM HTTP v1 API をお勧めします。デバイスからサーバーへのアップストリーム メッセージングが要件に含まれている場合は、XMPP プロトコルを実装する必要があります。

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 サーバー プロトコルの実装

メッセージを送信するために、アプリ サーバーは HTTP ヘッダーと、JSON キーと値のペアで構成される HTTP 本文を含む POST 要求を発行します。ヘッダーと本文のオプションの詳細については、アプリ サーバーの送信要求のビルドを参照してください。

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

FCM メッセージの JSON ペイロードは HTTP プロトコルに似ていますが、次の例外があります。

  • 複数の受信者はサポートされていません。
  • FCM は必須のフィールドmessage_idを追加します。この ID は、XMPP 接続でメッセージを一意に識別します。 FCM からの ACK または NACK は、 message_idを使用して、アプリ サーバーから FCM に送信されたメッセージを識別します。したがって、このmessage_idが (送信者 IDごとに) 一意であるだけでなく、常に存在することが重要です。
  • XMPP はサーバー キーを使用して、FCM への永続的な接続を承認します。詳細については、送信リクエストの承認を参照してください。

通常の FCM メッセージに加えて、制御メッセージが送信されます。これは、JSON オブジェクトのmessage_typeフィールドで示されます。値は、「ack」または「nack」、または「control」のいずれかです (以下の形式を参照)。 message_typeが不明な FCM メッセージは、サーバーによって無視される可能性があります。

アプリ サーバーが FCM から受信するデバイス メッセージごとに、ACK メッセージを送信する必要があります。 NACK メッセージを送信する必要はありません。メッセージの ACK を送信しない場合、メッセージの有効期限が切れていない限り、FCM は次に新しい XMPP 接続が確立されたときにメッセージを再送信します。

FCM は、サーバーからデバイスへのメッセージごとに ACK または NACK も送信します。どちらも受信しない場合は、操作の途中で TCP 接続が閉じられたことを意味し、サーバーはメッセージを再送信する必要があります。詳細については、フロー制御を参照してください。

すべてのメッセージ パラメータのリストについては、プロトコル リファレンスを参照してください。

リクエスト形式

ペイロード付きメッセージ — 通知メッセージ

通知メッセージの 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",
  }
  </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":"SomeInvalidRegistrationToken",
    "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@fcm.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 を送信する) 必要があります。

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

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

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

フロー制御

FCM に送信されるすべてのメッセージは、ACK または NACK 応答を受け取ります。これらの応答のいずれも受信していないメッセージは、保留中と見なされます。保留中のメッセージ数が 100 に達すると、アプリ サーバーは新しいメッセージの送信を停止し、FCM が既存の保留中のメッセージの一部を確認するまで待機する必要があります (図 1 を参照)。

FCM とアプリ サーバー間の制御フローの詳細図

図 1.メッセージ/ACK フロー。

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

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