Hosting REST API を使用してサイトにデプロイする

Firebase Hosting REST API を使用すると、Firebase によってホストされているサイトに、プログラムを使用したカスタマイズ可能な方法でデプロイできます。この REST API は、Hosting の新規または更新されたコンテンツ ファイルや構成ファイルをデプロイする場合に使用します。

Firebase CLI を使用してデプロイする代わりに、Firebase Hosting REST API を使用して、サイトのアセットの新しい version をプログラムで作成し、ファイルをこのバージョンにアップロードしてから、このバージョンをサイトにデプロイできます。

たとえば、Firebase Hosting REST API を使用すると、次のことができます。

  • デプロイのスケジュール。REST API と cron ジョブを組み合わせることにより、Firebase によってホストされたコンテンツを定期的に変更できます(たとえば、特別な休日やイベントに関連したバージョンのコンテンツをデプロイできます)。

  • デベロッパー ツールとの統合。1 回クリックするだけで(たとえば、IDE 内のデプロイボタンをクリックするだけで)Firebase Hosting にウェブアプリ プロジェクトをデプロイできるオプションを、ツール内に作成できます。

  • 静的コンテンツを生成する場合の自動デプロイ。静的コンテンツ(たとえば、wiki やニュース記事などのユーザー作成コンテンツ)をプログラムによって生成するプロセスの場合は、生成されたコンテンツを動的に提供するのではなく、静的ファイルとしてデプロイできます。こうすると、コストのかかる計算能力を節約し、ファイルをよりスケーラブルな方法で処理できます。

このガイドではまず、API の有効化、認証、承認を行う方法について説明します。次に、Firebase Hosting バージョンを作成し、必要なファイルをこのバージョンにアップロードして、最後にこのバージョンをデプロイする例を示します。

この REST API の詳細については、完全な Hosting REST API リファレンス ドキュメントもご確認ください。

始める前に: REST API を有効にする

Google API Console で Firebase Hosting REST API を有効にする必要があります。

  1. Google API Console で Firebase Hosting API ページを開きます。

  2. プロンプトが表示されたら、Firebase プロジェクトを選択します。

  3. Firebase Hosting API ページで [有効にする] をクリックします。

ステップ 1: API リクエストを認証して承認するためのアクセス トークンを取得する

Firebase プロジェクトでは Google サービス アカウントがサポートされています。これを使用して、アプリサーバーまたは信頼できる環境から Firebase サーバー API を呼び出せます。コードをローカルで開発している、または アプリケーションをオンプレミスでデプロイしている場合、このサービス アカウントで取得した認証情報を使用してサーバー リクエストを認可することができます。

サービス アカウントを認証して Firebase サービスへのアクセスを認可するには、秘密鍵ファイルを JSON 形式で生成する必要があります。

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

  1. Firebase コンソールで、[設定] > [サービス アカウント] を開きます。

  2. [新しい秘密鍵の生成] をクリックし、[キーを生成] をクリックして確定します。

  3. キーを含む JSON ファイルを安全に保管します。

次に示すように、有効期間の短い OAuth 2.0 アクセス トークンを取得するために、適切な言語の Google 認証ライブラリと一緒に Firebase 認証情報を使用します。

node.js

const {google} = require('googleapis');
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);
    });
  });
}

この例では、Google API クライアント ライブラリはリクエストを JSON Web Token(JWT)で認証します。詳細については、JSON Web 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();
}

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

ステップ 2: プロジェクトにデフォルトの Hosting サイトがあることを確認する

Firebase Hosting に初めてデプロイする前に、Firebase プロジェクトにデフォルトの Hosting SITE が必要です。

  1. sites.list エンドポイントを呼び出して、プロジェクトにデフォルトの Hosting サイトがすでに存在するかどうかを確認します。

    次に例を示します。

    cURL コマンド

    curl -H "Content-Type: application/json" \
           -H "Authorization: Bearer ACCESS_TOKEN" \
    
    https://firebasehosting.googleapis.com/v1beta1/projects/PROJECT_ID/sites
    

    未加工の HTTPS リクエスト

    Host: firebasehosting.googleapis.com
    
    POST /v1beta1/projects/PROJECT_ID/sites HTTP/1.1
    Authorization: Bearer ACCESS_TOKEN
    Content-Type: application/json
    
    • いずれかのサイトに "type": "DEFAULT_SITE" がある場合、プロジェクトにデフォルトの Hosting サイトがすでに存在します。この手順の残りをスキップして、次のステップ「サイトの新しいバージョンを作成する」に進みます。

    • 空の配列が返された場合、デフォルトの Hosting サイトはありません。このステップの残りの部分を完了します。

  2. デフォルトの Hosting サイトの SITE_ID を決定します。この SITE_ID を決定する際は、次の点に注意してください。

    • この SITE_ID は、次のデフォルトの Firebase サブドメインを作成するために使用されます。
      SITE_ID.web.appSITE_ID.firebaseapp.com

    • SITE_ID には次の要件があります。

      • 有効なホスト名ラベルでなければなりません。つまり、._ などを含めることはできません。
      • 30 文字以下にしてください。
      • Firebase 内でグローバルに一意である必要があります。

    通常は、デフォルトの Hosting サイトの SITE_ID としてプロジェクト ID を使用することをおすすめします。この ID を確認する方法については、Firebase プロジェクトについて理解するをご覧ください。

  3. 希望する SITE_IDsiteId パラメータとして使用して sites.create エンドポイントを呼び出し、デフォルトの Hosting サイトを作成します。

    次に例を示します。

    cURL コマンド

    curl -H "Content-Type: application/json" \
           -H "Authorization: Bearer ACCESS_TOKEN" \
    
    https://firebasehosting.googleapis.com/v1beta1/projects/PROJECT_ID/sites?siteId=SITE_ID
    

    未加工の HTTPS リクエスト

    Host: firebasehosting.googleapis.com
    
    POST /v1beta1/projects/PROJECT_ID/sites?siteId=SITE_ID
    Authorization: Bearer ACCESS_TOKEN
    Content-Type: application/json
    

    sites.create に対するこの API 呼び出しは、次の JSON を返します。

    {
      "name": "projects/PROJECT_ID/sites/SITE_ID",
      "defaultUrl": "https://SITE_ID.web.app",
      "type": "DEFAULT_SITE"
    }
    

ステップ 3: サイトの新しいバージョンを作成する

最初の API 呼び出しで行うのは、サイトの新しい Version を作成することです。このガイドの後半では、ファイルをこのバージョンにアップロードし、サイトにデプロイします。

  1. デプロイするサイトの SITE_ID を特定します。

  2. 呼び出し内で SITE_ID を使用して、versions.create エンドポイントを呼び出します。

    (省略可)呼び出し内で Firebase Hosting 構成オブジェクトを渡すこともできます。たとえば、指定した期間内のすべてのファイルをキャッシュに保存するヘッダーの設定などが該当します。

    次に例を示します。

    cURL コマンド

    curl -H "Content-Type: application/json" \
           -H "Authorization: Bearer ACCESS_TOKEN" \
           -d '{
                 "config": {
                   "headers": [{
                     "glob": "**",
                     "headers": {
                       "Cache-Control": "max-age=1800"
                     }
                   }]
                 }
               }' \
    https://firebasehosting.googleapis.com/v1beta1/sites/SITE_ID/versions
    

    未加工の HTTPS リクエスト

    Host: firebasehosting.googleapis.com
    
    POST /v1beta1/sites/SITE_ID/versions HTTP/1.1
    Authorization: Bearer ACCESS_TOKEN
    Content-Type: application/json
    Content-Length: 134
    
    {
      "config": {
        "headers": [{
          "glob": "**",
          "headers": {
            "Cache-Control": "max-age=1800"
          }
        }]
      }
    }
    

versions.create に対するこの API 呼び出しは、次の JSON を返します。

{
  "name": "sites/SITE_ID/versions/VERSION_ID",
  "status": "CREATED",
  "config": {
    "headers": [{
      "glob": "**",
      "headers": {
        "Cache-Control": "max-age=1800"
      }
    }]
  }
}

このレスポンスには、新しいバージョンの一意の識別子が sites/SITE_ID/versions/VERSION_ID の形式で含まれています。この特定のバージョンを参照するには、このガイド全体にわたってこの一意の識別子が必要になります。

ステップ 4: デプロイするファイルのリストを指定する

新しいバージョンの識別子が設定されたので、Firebase Hosting に対して、この新しいバージョンに最終的にデプロイするファイルを指定する必要があります。

Hosting では、個々のファイルに最大 2 GB のサイズ上限があります。

この API では、SHA256 ハッシュを使用してファイルを識別する必要があります。したがって、API 呼び出しを行う前に、まず、静的ファイルを Gzip 圧縮してから、新しく圧縮した各ファイルの SHA256 ハッシュを取り出して、各静的ファイルのハッシュを計算する必要があります。

この例では、新しいバージョンで 3 つのファイル file1file2file3 をデプロイします。

  1. ファイルを Gzip 圧縮します。

    gzip file1 && gzip file2 && gzip file3

    3 つの圧縮ファイル file1.gzfile2.gzfile3.gz が作成されます。

  2. 各圧縮ファイルの SHA256 ハッシュを取得します。

    cat file1.gz | openssl dgst -sha256
    
    66d61f86bb684d0e35f94461c1f9cf4f07a4bb3407bfbd80e518bd44368ff8f4
    
    cat file2.gz | openssl dgst -sha256
    
    490423ebae5dcd6c2df695aea79f1f80555c62e535a2808c8115a6714863d083
    
    cat file3.gz | openssl dgst -sha256
    
    59cae17473d7dd339fe714f4c6c514ab4470757a4fe616dfdb4d81400addf315
    

    3 つの圧縮ファイルの 3 つの SHA256 ハッシュが取得されました。

  3. これらの 3 つのハッシュを API リクエストに入れて、versions.populateFiles エンドポイントに送信します。各ハッシュは、アップロードされたファイルの目的のパスを使用して指定します(この例では /file1/file2/file3)。

    次に例を示します。

    cURL コマンド

    $ curl -H "Content-Type: application/json" \
             -H "Authorization: Bearer ACCESS_TOKEN" \
             -d '{
                   "files": {
                     "/file1": "66d61f86bb684d0e35f94461c1f9cf4f07a4bb3407bfbd80e518bd44368ff8f4",
                     "/file2": "490423ebae5dcd6c2df695aea79f1f80555c62e535a2808c8115a6714863d083",
                     "/file3": "59cae17473d7dd339fe714f4c6c514ab4470757a4fe616dfdb4d81400addf315"
                   }
                 }' \
    https://firebasehosting.googleapis.com/v1beta1/sites/SITE_ID/versions/VERSION_ID:populateFiles
    

    未加工の HTTPS リクエスト

    Host: firebasehosting.googleapis.com
    
    POST /v1beta1/sites/SITE_ID/versions/VERSION_ID:populateFiles HTTP/1.1
    Authorization: Bearer ACCESS_TOKEN
    Content-Type: application/json
    Content-Length: 181
    
    {
      "files": {
        "/file1": "66d61f86bb684d0e35f94461c1f9cf4f07a4bb3407bfbd80e518bd44368ff8f4",
        "/file2": "490423ebae5dcd6c2df695aea79f1f80555c62e535a2808c8115a6714863d083",
        "/file3": "59cae17473d7dd339fe714f4c6c514ab4470757a4fe616dfdb4d81400addf315"
      }
    }
    

versions.populateFiles に対するこの API 呼び出しは、次の JSON を返します。

{
  "uploadRequiredHashes": [
    "490423ebae5dcd6c2df695aea79f1f80555c62e535a2808c8115a6714863d083",
    "59cae17473d7dd339fe714f4c6c514ab4470757a4fe616dfdb4d81400addf315"
  ],
  "uploadUrl": "https://upload-firebasehosting.googleapis.com/upload/sites/SITE_ID/versions/VERSION_ID/files"
}

このレスポンスの内容は、次のとおりです。

  • アップロードする必要がある各ファイルのハッシュ。たとえば、この例では、file1 は以前のバージョンですでにアップロードされているため、このハッシュは uploadRequiredHashes リストに含まれていません。

  • 新しいバージョンに固有の uploadUrl

次の手順で 2 つの新しいファイルをアップロードするには、これらのハッシュと、versions.populateFiles のレスポンス内の uploadURL を使用する必要があります。

ステップ 5: 必要なファイルをアップロードする

必要なファイル(この前の手順で versions.populateFiles レスポンスの uploadRequiredHashes で指定されたファイル)を個別にアップロードする必要があります。これらのファイルをアップロードするには、ファイルのハッシュと前の手順の uploadUrl が必要です。

  1. uploadUrl の前にスラッシュファイルのハッシュを追加して、ファイル固有の URL を次の形式で作成します。https://upload-firebasehosting.googleapis.com/upload/sites/SITE_ID/versions/VERSION_ID/files/FILE_HASH

  2. 一連のリクエストを使用して、ファイル固有の URL に、必要なすべてのファイルを 1 つずつアップロードします(この例では file2.gzfile3.gz のみ)。

    たとえば、圧縮された file2.gz をアップロードするには、次のようにします。

    cURL コマンド

    curl -H "Authorization: Bearer ACCESS_TOKEN" \
           -H "Content-Type: application/octet-stream" \
           --data-binary @./file2.gz \
    https://upload-firebasehosting.googleapis.com/upload/sites/SITE_ID/versions/VERSION_ID/files/FILE_HASH
    

    未加工の HTTPS リクエスト

    Host: upload-firebasehosting.googleapis.com
    
    POST /upload/sites/SITE_ID/versions/VERSION_ID/files/FILE_HASH HTTP/1.1
    Authorization: Bearer ACCESS_TOKEN
    Content-Type: application/octet-stream
    Content-Length: 500
    
    content-of-file2.gz
    

アップロードに成功すると、200 OK HTTPS レスポンスが返されます。

ステップ 6: バージョンのステータスを FINALIZED に更新する

versions.populateFiles のレスポンス内で指定されているすべてのファイルをアップロードしたら、バージョンのステータスを FINALIZED に更新できます。

API リクエストの status フィールドを FINALIZED に設定して、versions.patch エンドポイントを呼び出します。

次に例を示します。

cURL コマンド

curl -H "Content-Type: application/json" \
       -H "Authorization: Bearer ACCESS_TOKEN" \
       -X PATCH \
       -d '{"status": "FINALIZED"}' \
https://firebasehosting.googleapis.com/v1beta1/sites/SITE_ID/versions/VERSION_ID?update_mask=status

未加工の HTTPS リクエスト

Host: firebasehosting.googleapis.com

PATCH /v1beta1/sites/SITE_ID/versions/VERSION_ID?update_mask=status HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
Content-Length: 23

{"status": "FINALIZED"}

versions.patch に対するこの API 呼び出しは、次の JSON を返します。statusFINALIZED に更新されていることを確認します。

{
  "name": "sites/SITE_ID/versions/VERSION_ID",
  "status": "FINALIZED",
  "config": {
    "headers": [{
      "glob": "**",
      "headers": {"Cache-Control": "max-age=1800"}
    }]
  },
  "createTime": "2018-12-02T13:41:56.905743Z",
  "createUser": {
    "email": "SERVICE_ACCOUNT_EMAIL@SITE_ID.iam.gserviceaccount.com"
  },
  "finalizeTime": "2018-12-02T14:56:13.047423Z",
  "finalizeUser": {
    "email": "USER_EMAIL@DOMAIN.tld"
  },
  "fileCount": "5",
  "versionBytes": "114951"
}

ステップ 7: デプロイ用にバージョンをリリースする

これでファイナライズ バージョンが作成されたので、デプロイ用にリリースします。この手順では、ホスティング構成と新しいバージョンのすべてのコンテンツ ファイルを含むバージョンの Release を作成する必要があります。

releases.create エンドポイントを呼び出して、リリースを作成します。

次に例を示します。

cURL コマンド

curl -H "Authorization: Bearer ACCESS_TOKEN" \
       -X POST
https://firebasehosting.googleapis.com/v1beta1/sites/SITE_ID/releases?versionName=sites/SITE_ID/versions/VERSION_ID

未加工の HTTPS リクエスト

Host: firebasehosting.googleapis.com

POST /v1beta1/sites/SITE_ID/releases?versionName=sites/SITE_ID/versions/VERSION_ID HTTP/1.1
Authorization: Bearer ACCESS_TOKEN

releases.create に対するこの API 呼び出しは、次の JSON を返します。

{
  "name": "sites/SITE_ID/releases/RELEASE_ID",
  "version": {
    "name": "sites/SITE_ID/versions/VERSION_ID",
    "status": "FINALIZED",
    "config": {
    "headers": [{
      "glob": "**",
      "headers": {"Cache-Control": "max-age=1800"}
    }]
  }
  },
  "type": "DEPLOY",
  "releaseTime": "2018-12-02T15:14:37Z"
}

これで、ホスティング構成と新しいバージョンに関するすべてのファイルがサイトにデプロイされ、URL を使用してファイルにアクセスできるようになりました。

  • https://SITE_ID.web.app/file1
  • https://SITE_ID.web.app/file2
  • https://SITE_ID.web.app/file3

これらのファイルには、SITE_ID.firebaseapp.com ドメインに関連付けられた URL からアクセスすることもできます。

新しいリリースの表示は、Firebase コンソールの Hosting ダッシュボードでも確認できます。