Google Cloud와 통합

Cloud Storage for FirebaseGoogle Cloud와 긴밀하게 통합됩니다. Cloud StorageFirebase SDK는 Google Cloud Storage 버킷에 직접 파일을 저장하며 앱이 성장함에 따라 다른 Google Cloud 서비스(예: App Engine 또는 Cloud Functions와 같은 관리형 컴퓨팅) 또는 머신러닝 API(예: Cloud Vision 또는 Google 번역)를 통합할 수 있습니다.

Firebase 프로젝트는 실제로는 사용 설정된 Firebase 관련 구성과 서비스가 추가적으로 포함된 Google Cloud 프로젝트입니다. 즉, Cloud Storage for Firebase와 함께 사용하는 모든 Cloud Storage 버킷은 Google Cloud (콘솔 및 API 포함)에서 액세스할 수 있습니다.

기존 Cloud Storage 버킷 가져오기를 포함하여 Google Cloud와 통합하려면 사용한 만큼만 지불하는 Blaze 요금제를 사용하는 Firebase 프로젝트가 필요합니다.

서비스 계정 고려사항

Firebase는 Google Cloud 서비스 계정을 사용하여 사용자 인증 정보를 공유하지 않고 서비스를 운영하고 관리합니다. Cloud Storage를 사용하는 Firebase 프로젝트를 만들면 프로젝트에서 해당 서비스 계정을 이미 사용할 수 있다는 것을 알 수 있습니다. service-PROJECT_NUMBER@gcp-sa-firebasestorage.iam.gserviceaccount.com. 자세한 내용은 Firebase 서비스 계정 개요를 참고하세요.

Google Cloud Storage

Google Cloud Storage API를 사용하여 Cloud StorageFirebase SDK를 통해 업로드된 파일에 액세스할 수 있으며 파일 복사나 이동, 참조 위치에서 사용 가능한 모든 파일 나열과 같은 복잡한 작업도 수행할 수 있습니다.

이러한 요청에서는 Firebase AuthenticationCloud Storage Security Rules가 아닌 Google Cloud Storage 액세스 제어 옵션을 사용한다는 점에 유의해야 합니다.

API

Cloud StorageFirebase SDK 외에도 Cloud Storage 버킷에 저장된 데이터를 액세스하는 데는 원하는 작업이 무엇인지에 따라 여러 방법이 있습니다. 서버에 있는 데이터를 액세스하려면 Google에서 제공하는 서버 측 라이브러리 및 JSON, S3 호환 XML RESTful API를 사용하면 됩니다. 변경사항을 기록하거나 다른 관리 작업을 수행하는 데는 명령줄 도구가 유용합니다.

Google Cloud 서버 SDK

Google CloudCloud Storage를 비롯하여 다양한 클라우드 제품을 위한 고품질 서버 SDK를 제공합니다. 이러한 라이브러리는 Node.js, Java, Go, Python, PHP, Ruby로 제공됩니다.

설치 안내, 인증, 문제 해결 등의 자세한 내용은 위에 링크된 플랫폼별 문서를 참조하세요.

다음은 Google Cloud Storage SDK의 사용 예시입니다.

Node.js

    // Require gcloud
    var gcloud = require('google-cloud');

    // Enable Cloud Storage
    var gcs = gcloud.storage({
      projectId: 'grape-spaceship-123',
      keyFilename: '/path/to/keyfile.json'
    });

    // Reference an existing bucket.
    var bucket = gcs.bucket('my-existing-bucket');

    // Upload a local file to a new file to be created in your bucket.
    bucket.upload('/photos/zoo/zebra.jpg', function(err, file) {
      if (!err) {
        // "zebra.jpg" is now in your bucket.
      }
    });

    // Download a file from your bucket.
    bucket.file('giraffe.jpg').download({
      destination: '/photos/zoo/giraffe.jpg'
    }, function(err) {});
    

자바

    // Enable Cloud Storage
    Storage storage = StorageOptions.builder()
      .authCredentials(AuthCredentials.createForJson(new FileInputStream("/path/to/my/key.json"))
      .build()
      .service();

    // Upload a local file to a new file to be created in your bucket.
    InputStream uploadContent = ...
    BlobId blobId = BlobId.of("my-existing-bucket", "zebra.jpg");
    BlobInfo blobInfo = BlobInfo.builder(blobId).contentType("text/plain").build();
    Blob zebraBlob = storage.create(blobInfo, content);

    // Download a file from your bucket.
    Blob giraffeBlob = storage.get("my-existing-bucket", "giraffe.jpg", null);
    InputStream downloadContent = giraffeBlob.getInputStream();
    

Go

    // Enable Cloud Storage
    client, err := storage.NewClient(ctx, option.WithServiceAccountFile("path/to/keyfile.json"))
    if err != nil {
        log.Fatal(err)
    }

    // Download a file from your bucket.
    rc, err := client.Bucket("my-existing-bucket").Object("giraffe.jpg").NewReader(ctx)
    if err != nil {
        log.Fatal(err)
    }
    defer rc.Close()
    body, err := ioutil.ReadAll(rc)
    if err != nil {
        log.Fatal(err)
    }
    

Python

    # Import gcloud
    from google.cloud import storage

    # Enable Cloud Storage
    client = storage.Client()

    # Reference an existing bucket.
    bucket = client.get_bucket('my-existing-bucket')

    # Upload a local file to a new file to be created in your bucket.
    zebraBlob = bucket.get_blob('zebra.jpg')
    zebraBlob.upload_from_filename(filename='/photos/zoo/zebra.jpg')

    # Download a file from your bucket.
    giraffeBlob = bucket.get_blob('giraffe.jpg')
    giraffeBlob.download_as_string()
    

PHP

    // Require gcloud
    require 'vendor/autoload.php';
    use Google\Cloud\Storage\StorageClient;

    // Enable Cloud Storage
    $storage = new StorageClient([
        'projectId' => 'grape-spaceship-123'
    ]);

    // Reference an existing bucket.
    $bucket = $storage->bucket('my-existing-bucket');

    // Upload a file to the bucket.
    $bucket->upload(
        fopen('/photos/zoo/zebra.jpg', 'r')
    );

    // Download a file from your bucket.
    $object = $bucket->object('giraffe.jpg');
    $object->downloadToFile('/photos/zoo/giraffe.jpg');
    

Ruby

    # Require gcloud
    require "google/cloud"

    # Enable Cloud Storage
    gcloud = Google::Cloud.new "grape-spaceship-123", "/path/to/keyfile.json"
    storage = gcloud.storage

    # Reference an existing bucket.
    bucket = storage.bucket "my-existing-bucket"

    # Upload a file to the bucket.
    bucket.create_file "/photos/zoo/zebra.jpg", "zebra.jpg"

    # Download a file from your bucket.
    file = bucket.file "giraffe.jpg"
    file.download "/photos/zoo/#{file.name}"
    

REST API

클라이언트 라이브러리 없이 언어를 사용하거나, 클라이언트 라이브러리가 수행하지 않는 작업을 하려고 하거나, 선호하는 HTTP 클라이언트가 있는 경우 Google Cloud Storage에서 JSONXML용 API를 제공합니다.

이러한 스토리지 데이터 액세스 API 외에도 Cloud Storage for Firebase API를 사용해 Firebase 프로젝트에 사용할 Cloud Storage 버킷을 관리할 수 있습니다.

gsutil

gsutilCloud Storage에 직접 액세스할 수 있는 명령줄 도구입니다. gsutil로 다음을 비롯하여 광범위한 버킷 및 객체 관리 작업을 수행할 수 있습니다.

  • 객체 업로드, 다운로드, 삭제
  • 버킷 및 객체 나열
  • 객체 이동, 복사 및 이름 바꾸기
  • 객체 및 버킷 ACL 수정

gsutil은 디렉터리 간 파일 이동, 특정 위치 아래의 모든 파일 삭제와 같은 고급 기능도 지원합니다.

다음과 같이 한 참조의 모든 파일을 다른 참조로 손쉽게 이동할 수 있습니다.

gsutil mv gs://bucket/old/reference gs://bucket/new/reference

참조 위치 아래의 모든 파일을 일괄 삭제하는 방법도 매우 간단합니다.

# Delete all files under a path
gsutil rm -r gs://bucket/reference/to/delete

# Delete all the files in a bucket but not the bucket gsutil rm -r gs://bucket/**

# Delete all the files AND the bucket # Removing the default bucket will break the Firebase SDKs for Cloud Storage and is strongly discouraged gsutil rm -r gs://bucket

요청 비율

Google Cloud Storage는 자동 확장 기술을 사용하여 매우 높은 수준의 요청 비율을 달성하는 고도로 확장 가능한 서비스입니다.

Google Cloud Storage는 멀티 테넌트 서비스이므로 사용자들이 동일한 기본 리소스 집합을 공유합니다. 이러한 공유된 리소스를 최대한 활용하기 위해 버킷은 초기 IO 용량을 가지고 있습니다.

Cloud Storage for Firebase를 앱에 통합할 계획이라면 우수한 성능을 얻기 위해 앱에 필요한 최소 요청 비율과 효율적으로 요청하는 방법을 고려하세요. 요청 비율, 특히 요청 비율 늘리기에 대한 가이드라인을 검토하세요.

객체 버전 관리

백업해 두지 않은 항목을 실수로 삭제한 적이 있으신가요? Google Cloud Storage는 데이터를 자동으로 백업하고 백업에서 복원하는 객체 버전 관리를 지원합니다. gsutil versioning set 명령어를 사용하여 객체 버전 관리를 사용 설정할 수 있습니다.

gsutil versioning set on gs://<your-cloud-storage-bucket>

Cloud Storage는 항상 가장 최근 버전을 선택하므로 객체를 복원하려는 경우 위 API 또는 도구 중 하나를 사용하여 원하는 객체를 가장 최근 객체로 설정해야 합니다.

객체 수명 주기 관리

비활성 파일을 자동으로 보관 처리하거나 삭제하는 기능은 여러 애플리케이션에서 매우 유용합니다. Google Cloud Storage가 제공하는 객체 수명 주기 관리로 특정 시간이 지난 객체를 삭제하거나 보관 처리할 수 있습니다.

사진 공유 애플리케이션에서 모든 사진을 하루 이내에 삭제해야 한다고 가정해 보겠습니다. 객체 수명 주기 정책을 아래와 같이 설정하면 됩니다.

// lifecycle.json
{
  "lifecycle": {
    "rule":
    [
      {
        "action": {"type": "Delete"},
        "condition": {"age": 1}
      }
    ]
  }
}

gsutil lifecycle set 명령어를 사용하여 배포합니다.

gsutil lifecycle set lifecycle.json gs://<your-cloud-storage-bucket>

이는 버킷의 모든 파일에 적용되므로, 매일 삭제하려는 사진과 장기간 보관하고자 하는 중요한 사용자 백업을 함께 저장하는 경우 별도의 버킷 두 개를 사용하거나 gsutil 또는 자체 서버로 수동으로 삭제하는 것이 좋습니다.

Google Cloud Functions(베타)

Google Cloud Functions는 이벤트 기반의 경량형 비동기 컴퓨팅 솔루션으로, 서버나 런타임 환경을 관리할 필요 없이 이벤트에 응답하는 것이 유일한 목적인 소형 함수를 만들 수 있습니다. 동영상 트랜스코딩, 머신러닝을 사용한 이미지 분류, Firebase Realtime Database와의 메타데이터 동기화 등의 작업에 이러한 함수를 사용할 수 있습니다. Cloud Functions는 App Engine보다 오버헤드가 훨씬 낮으므로 Cloud Storage의 변경에 반응하는 가장 빠른 방법입니다.

Google Cloud Vision API

개발자는 강력한 머신러닝 모델을 사용하기 쉬운 API로 통합한 Google Cloud Vision API를 사용하여 이미지의 내용을 파악할 수 있습니다. 이 API는 이미지를 수천 가지 카테고리로 빠르게 분류하고, 이미지 안의 개별 물체와 얼굴을 감지하고, 이미지에 포함된 글자를 찾아서 판독하고, 부적절한 콘텐츠를 식별하고, 이미지 감정 분석도 제공합니다.

Google Cloud Speech API

Vision API와 마찬가지로 개발자는 Google Cloud Speech API를 사용해서 Cloud Storage에 저장된 오디오 파일에서 텍스트를 추출할 수 있습니다. 이 API는 글로벌 사용자층을 지원하기 위해 80가지 이상의 언어와 방언을 인식합니다. 이 API를 Google Cloud Natural Language API와 결합하면 원시 텍스트를 추출하는 동시에 텍스트의 의미를 추론할 수 있습니다. 또한 전 세계 잠재고객을 지원해야 한다면 Google 번역 API와 결합하여 텍스트를 90개 이상의 언어로 번역할 수 있습니다.

Google App Engine

Google App Engine은 백엔드 로직을 수신 트래픽의 양에 비례하여 자동으로 확장하는 'Platform as a Service'입니다. 백엔드 코드만 업로드하면 Google에서 앱의 가용성을 관리해 주므로 개발자는 별도의 서버를 프로비저닝하거나 유지할 필요가 없습니다. App Engine를 사용하면 Firebase 애플리케이션에 처리 능력이나 신뢰할 수 있는 실행을 빠르고 간단하게 추가할 수 있습니다.

이름 형식이 PROJECT_ID.appspot.com인 기본 Cloud Storage 버킷이 있는 경우 프로젝트의 App Engine 앱과 자동으로 공유됩니다. 즉, App Engine 앱을 빌드하는 경우 기본 제공되는 App Engine API를 사용하여 해당 버킷과 App Engine 간에 데이터를 공유할 수 있습니다. 이 방법은 오디오 인코딩, 동영상 트랜스코딩, 이미지 변환 및 계산 집약적인 기타 백그라운드 처리를 수행할 때 유용합니다.

App Engine을 위한 Java, Python, Go 표준 환경에 포함된 App Engine Images API(Java | Python | Go)를 사용하여 이미지 크기 조절, 회전, 뒤집기, 자르기 등을 수행하고 Cloudinary 및 Imgix와 유사하게 클라이언트 측 변환을 허용하는 이미지 제공 URL을 반환할 수 있습니다.

Firebase에 기존 Google Cloud 프로젝트를 가져올 때 기존 App Engine 객체를 Firebase에서 사용 가능하게 만들려면 gsutil에서 다음 명령어를 실행하여 객체에 기본 액세스 제어를 설정하고 Firebase의 액세스를 허용해야 합니다.

gsutil -m acl ch -r -u service-PROJECT_NUMBER@gcp-sa-firebasestorage.iam.gserviceaccount.com gs://BUCKET_NAME

Firebase Security RulesApp Engine 파일 고려사항

이름 형식이 *.appspot.com인 기본 Cloud Storage 버킷이 있는 경우 프로젝트에 이 버킷을 공유하는 App Engine 앱도 있습니다.

공개 (인증되지 않음) 액세스를 위해 Firebase Security Rules를 구성하면 새로 업로드한 App Engine 파일도 공개적으로 액세스할 수 있게 됩니다.

Cloud StorageApp Engine의 알려진 문제

App Engine 앱을 가져올 수 없는 경우는 두 가지로 알려져 있습니다.

  1. 프로젝트에 기존 App Engine Datastore 마스터/슬레이브 앱이 포함된 경우
  2. 프로젝트 ID에 도메인 프리픽스가 포함된 경우(예: domain.com:project-1234)

이러한 두 가지 경우에 프로젝트는 Cloud Storage for Firebase를 지원하지 않으므로 Cloud Storage를 사용하려면 새 Firebase 프로젝트를 만들어야 합니다. 지원팀에 문의하면 도움을 받을 수 있습니다.