使用 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 托管的内容(例如,部署与特殊节日或事件相关的内容版本)。

  • 与开发者工具集成。您可以在自己的工具中创建一个选项,只需点击一下即可将 Web 应用项目部署到 Firebase Hosting(例如,点击 IDE 中的部署按钮)。

  • 在生成静态内容时自动部署。当某个进程以编程方式生成静态内容(例如,Wiki 或新闻文章等由用户生成的内容)时,您可以将生成的内容部署为静态文件,而不是动态地提供这些内容。这可以为您节省昂贵的计算资源,并以更具可伸缩性的方式提供文件。

本指南首先介绍如何启用 API 并对其进行身份验证和授权,然后通过一个示例来逐步演示如何创建 Firebase Hosting 版本,将所需文件上传到该版本,最后部署该版本。

您还可以在完整的 Hosting REST API 参考文档中了解此 REST API 的相关详情。

准备工作:启用 REST API

您必须在 Google API 控制台中启用 Firebase Hosting REST API:

  1. 在 Google API 控制台中打开 Firebase Hosting API 页面

  2. 出现提示时,选择您的 Firebase 项目。

  3. 点击 Firebase Hosting API 页面上的启用

第 1 步:获取访问令牌以对 API 请求进行身份验证和授权

Firebase 项目支持 Google 服务账号,您可以使用这些账号从应用服务器或受信任环境调用 Firebase 服务器 API。如果您是在本地编写代码,或是在本地部署您的应用,则可以使用通过此服务账号获取的凭据来对服务器请求进行授权。

如需对服务账号进行身份验证并授予其访问 Firebase 服务的权限,您必须生成 JSON 格式的私钥文件。

如需为您的服务账号生成私钥文件,请执行以下操作:

  1. Firebase 控制台中,依次打开设置 > 服务账号

  2. 点击生成新的私钥,然后点击生成密钥进行确认。

  3. 妥善存储包含密钥的 JSON 文件。

将您的 Firebase 凭据与适用于您的偏好语言的 Google Auth 库结合使用,以检索短期有效的 OAuth 2.0 访问令牌:

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 令牌 (JWT) 对请求进行身份验证。有关详情,请参阅 JSON Web 令牌

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 中必须保持全局唯一

    请注意,我们通常建议您使用项目 ID 作为默认 Hosting 网站的 SITE_ID。如需了解如何查找此 ID,请参阅了解 Firebase 项目

  3. 通过使用所需的 SITE_ID 作为 siteId 参数调用 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 哈希值。

继续讨论我们的示例,假设您要在新版本中部署三个文件:file1file2file3

  1. 用 Gzip 压缩文件:

    gzip file1 && gzip file2 && gzip file3

    您现在有三个压缩文件 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
    

    您现在拥有了三个压缩文件的三个 SHA256 哈希值。

  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

下一步是上传这两个新文件,您将需要这些哈希值和来自 versions.populateFiles 响应的 uploadURL

第 5 步:上传必需的文件

您需要单独上传每个必需的文件(这些文件由上一步中来自 versions.populateFiles 响应的 uploadRequiredHashes 列出)。上传这些文件时,您需要上一步中的文件哈希值和 uploadUrl

  1. uploadUrl 后附加正斜杠文件哈希值来创建文件专属网址,格式如下:https://upload-firebasehosting.googleapis.com/upload/sites/SITE_ID/versions/VERSION_ID/files/FILE_HASH

  2. 使用一系列请求将所有必需文件(在此示例中,只有 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

调用 versions.patch 端点,并将 API 请求中的 status 字段设置为 FINALIZED

例如:

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。请检查 status 是否已更新为 FINALIZED

{
  "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"
}

现在新版本的托管配置和所有文件应该都已部署到您的网站,而且您可以使用以下网址访问您的文件了:

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

这些文件还可以通过与您的 SITE_ID.firebaseapp.com 网域关联的网址进行访问。

您还可以在 Firebase 控制台的 Hosting 信息中心内看到新版本。