호스팅 REST API를 사용하여 사이트에 배포

Firebase Hosting REST API를 사용하면 Firebase 호스팅 사이트에 프로그래매틱 방식으로 맞춤설정 가능한 배포를 할 수 있습니다. 이 REST API를 사용하여 새로운 또는 업데이트된 Hosting 콘텐츠 및 구성을 배포합니다.

배포를 위해 Firebase CLI 대신 Firebase Hosting REST API를 사용하여 프로그래매틱 방식으로 사이트 애셋의 새 version을 만들어서 파일을 버전에 업로드한 다음 이 버전을 사이트에 배포할 수 있습니다.

다음은 Firebase Hosting REST API로 할 수 있는 작업의 몇 가지 예입니다.

  • 배포 예약. 크론 작업과 함께 REST API를 사용하면 정기적인 일정으로 Firebase 호스팅 콘텐츠를 변경할 수 있습니다(예: 콘텐츠의 특별한 기념일 또는 이벤트 관련 버전 배포).

  • 개발자 도구와 통합. 도구에서 단 한 번의 클릭만으로 웹 앱 프로젝트를 Firebase Hosting에 배포하는 옵션을 만들 수 있습니다(예: IDE에서 배포 버튼을 클릭).

  • 정적 콘텐츠 생성 시 자동 배포. 프로세스가 프로그래매틱 방식으로 정적 콘텐츠를 생성하면(예: 위키 또는 뉴스 기사와 같은 사용자 제작 콘텐츠) 생성된 콘텐츠를 동적으로 제공하지 않고 정적 파일로 배포할 수 있습니다. 이렇게 하면 비싼 컴퓨터 성능을 절약하고 보다 확장 가능한 방식으로 파일을 제공할 수 있습니다.

이 가이드에서는 먼저 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 프로젝트는 앱 서버 또는 신뢰할 수 있는 환경에서 Firebase 서버 API를 호출하는 데 사용할 수 있는 Google 서비스 계정을 지원합니다. 로컬에서 코드를 개발하거나 온프레미스에 애플리케이션을 배포하는 경우 이 서비스 계정을 통해 가져온 사용자 인증 정보를 사용하여 서버 요청을 승인할 수 있습니다.

서비스 계정을 인증하고 Firebase 서비스에 액세스하도록 승인하려면 JSON 형식의 비공개 키 파일을 생성해야 합니다.

서비스 계정의 비공개 키 파일을 생성하려면 다음 안내를 따르세요.

  1. Firebase Console에서 설정 > 서비스 계정을 엽니다.

  2. 새 비공개 키 생성을 클릭한 다음 키 생성을 클릭하여 확인합니다.

  3. 키가 들어있는 JSON 파일을 안전하게 저장합니다.

원하는 언어의 Google 인증 라이브러리와 함께 Firebase 사용자 인증 정보를 사용하여 수명이 짧은 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 웹 토큰(JWT)을 사용해 요청을 인증하는 방법을 설명합니다. 자세한 내용은 JSON 웹 토큰을 참조하세요.

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

자바

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 사이트의 프로젝트 ID를 SITE_ID로 사용하는 것을 권장합니다. Firebase 프로젝트 이해에서 이 ID를 찾는 방법을 알아보세요.

  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은 개별 파일의 최대 크기 한도가 2GB로 제한됩니다.

이 API를 사용하려면 SHA256 해시로 파일을 식별해야 합니다. 따라서 API를 호출하기 전에 먼저 파일을 Gzip으로 압축한 후 새로 압축한 파일의 SHA256 해시를 가져와 각 정적 파일마다 해시를 계산합니다.

이 예시에서는 file1, file2, file3라는 새로운 버전의 파일 3개를 배포하려고 한다고 가정해 보겠습니다.

  1. 파일을 Gzip으로 압축합니다.

    gzip file1 && gzip file2 && gzip file3

    이제 3개의 압축 파일 file1.gz, file2.gz, file3.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개의 압축 파일의 SHA256 해시 3개가 생겼습니다.

  3. API 요청에서 이 3가지 해시를 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에 추가하여 https://upload-firebasehosting.googleapis.com/upload/sites/SITE_ID/versions/VERSION_ID/files/FILE_HASH 형식으로 파일별 URL을 만듭니다.

  2. 일련의 요청을 사용하여 모든 필수 파일을 파일별 URL에 하나씩 업로드합니다(이 예시에서는 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로 업데이트할 수 있습니다.

FINALIZED로 설정된 API 요청의 status 필드를 사용하여 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 Console의 Hosting 대시보드에 새 출시 버전이 표시된 것을 확인할 수 있습니다.