送信リクエストを承認する

アプリサーバーや信頼できる環境から FCM に送信されるリクエストには、承認が必要です。以前の HTTP API と HTTP v1 API の承認には、次のような重要な違いがあります。

  • FCM HTTP v1 API では、Firebase プロジェクトに関連付けられたサービス アカウント用に生成される有効期間が短い OAuth 2.0 アクセス トークンが使用されます。
  • レガシー プロトコルでは、Firebase コンソールから取得される有効期間が長い API キーが使用されます。

いずれの場合も、FCM に送信される各メッセージ リクエストに、必要な認証情報を追加する必要があります。必ず正しい種類の認証情報を使用してください。API キーは以前の API へのリクエストの承認にしか使用できず、アクセス トークンは HTTP v1 API でしか使用できません。

HTTP v1 の送信リクエストを承認する

すべての Firebase プロジェクトには、デフォルトのサービス アカウントがあります。このアカウントを使用して、アプリサーバーまたは信頼できる環境から Firebase サーバー API を呼び出すことができます。別のサービス アカウントを使用する場合は、そのアカウントに編集者またはオーナーの権限があることを確認してください。

サービス アカウントを認証して、そのアカウントが Firebase サービスにアクセスすることを承認するには、JSON 形式の秘密鍵ファイルを生成し、このキーを使用して有効期間が短い OAuth 2.0 トークンを取得する必要があります。有効なトークンを取得したら、Remote Config や FCM などのさまざまな Firebase サービスの必要に応じて、サーバー リクエストにトークンを追加できます。

サービス アカウント用の秘密鍵ファイルを生成するには:

  1. Firebase コンソールで、[設定] > [サービス アカウント] を開きます。
  2. [新しい秘密鍵の生成] をクリックし、[キーを生成] をクリックして確認します。
  3. キーを含む JSON ファイルを安全に保管します。これを行うには、次のステップを実行する必要があります。

アクセス トークンを取得するには:

トークンを取得するには、プライベート キー JSON ファイルを参照する、以下の適切な言語の Google API クライアント ライブラリを使用できます。

node.js

 function getAccessToken() {
  return new Promise(function(resolve, reject) {
    var key = require('./service-account.json');
    var jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

Python

def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = ServiceAccountCredentials.from_json_keyfile_name(
      'service-account.json', SCOPES)
  access_token_info = credentials.get_access_token()
  return access_token_info.access_token

Java

private static String getAccessToken() throws IOException {
  GoogleCredential googleCredential = GoogleCredential
      .fromStream(new FileInputStream("service-account.json"))
      .createScoped(Arrays.asList(SCOPES));
  googleCredential.refreshToken();
  return googleCredential.getAccessToken();
}

トークンが期限切れになると、更新されたトークンを取得するために、トークンの更新メソッドが自動的に呼び出されます。

FCM へのアクセスを承認するには、スコープ https://www.googleapis.com/auth/firebase.messaging をリクエストします。

アクセス トークンを HTTP リクエスト ヘッダーに追加するには:

トークンを Authorization ヘッダーの値として Authorization: Bearer <access_token> という形式で追加します。

node.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Python

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

Java

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

レガシー プロトコルの送信リクエストを承認する

HTTP レガシー プロトコルでは、各リクエストに、Firebase コンソールの [設定] ペインの [クラウド メッセージング] タブにあるサーバーキーが含まれている必要があります。XMPP の場合は、同じサーバーキーを使用して接続を確立する必要があります。

HTTP リクエストを承認する

メッセージ リクエストは、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 プロトコル リファレンスには、メッセージに含めることができるすべてのパラメータのリストがあります。

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

メッセージを送信するときに、認証エラーが起こった場合は、サーバーキーの有効性を確認してください。たとえば 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 ステータス コードが返された場合、そのサーバーキーは有効ではありません。

XMPP 接続を承認する

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

長時間継続する 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 件の同時接続を許可します。

次のスニペットは、FCM への XMPP 接続の認証と承認を行う方法を示しています。

XMPP サーバー

XMPP サーバーは FCM への接続をリクエストします

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

FCM

FCM は接続を開き、PLAIN メソッドを含む認証メカニズムをリクエストします。

<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>

XMPP サーバー

XMPP サーバーは PLAIN 認証メソッドを使用して応答する必要があります。その際、Firebase コンソールの [設定] ペインの [クラウド メッセージング] タブにあるサーバーキーを提供します。

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

FCM

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

XMPP サーバー

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

FCM

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

XMPP サーバー

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

FCM

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

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

送信リクエストの作成の詳細については、送信リクエストの作成をご覧ください。レガシー XMPP プロトコル リファレンスには、メッセージに含めることができるすべてのパラメータのリストがあります。

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

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