C++로 Cloud Storage에 파일 업로드

Cloud Storage for Firebase를 사용하면 Firebase에서 제공하고 관리하는 Cloud Storage 버킷에 파일을 빠르고 손쉽게 업로드할 수 있습니다.

참조 만들기

파일을 업로드하려면 먼저 Cloud Storage에서 파일을 업로드할 위치를 가리키는 Cloud Storage 참조를 만듭니다.

Cloud Storage 버킷의 루트에 하위 경로를 추가하여 참조를 만들 수 있습니다.

// Create a root reference
StorageReference storage_ref = storage->GetReference();

// Create a reference to "mountains.jpg"
StorageReference mountains_ref = storage_ref.Child("mountains.jpg");

// Create a reference to 'images/mountains.jpg'
StorageReference mountain_images_ref = storage_ref.Child("images/mountains.jpg");

// While the file names are the same, the references point to different files
mountains_ref.name() == mountain_images_ref.name();           // true
mountains_ref.full_path() == mountain_images_ref.full_path(); // false

Cloud Storage 버킷의 루트를 가리키는 참조로는 데이터를 업로드할 수 없습니다. 참조는 하위 URL을 가리켜야 합니다.

파일 업로드

참조가 만들어졌으면 2가지 방법으로 Cloud Storage에 파일을 업로드할 수 있습니다.

  1. 메모리의 바이트 버퍼에서 업로드
  2. 기기의 파일을 나타내는 파일 경로에서 업로드

메모리 데이터에서 업로드

PutData() 메서드는 Cloud Storage에 파일을 업로드하는 가장 간단한 방법입니다. PutData()는 바이트 버퍼를 사용하며, Future가 완료되면 파일에 대한 정보를 포함하는 Future<Metadata>를 반환합니다. Controller를 사용하여 업로드를 관리하고 상태를 모니터링할 수 있습니다.

// Data in memory
const size_t kByteBufferSize = ...
uint8_t byte_buffer[kByteBufferSize] = { ... };

// Create a reference to the file you want to upload
StorageReference rivers_ref = storage_ref.Child("images/rivers.jpg");

// Upload the file to the path "images/rivers.jpg"
Future future = rivers_ref.PutBytes(byte_buffer, kByteBufferSize);

현재 요청은 이미 전송되었지만 파일을 업로드하려면 Future가 완료될 때까지 기다려야 하는 상태입니다. 게임은 대개 루프로 실행되고 다른 애플리케이션보다 콜백에 덜 의존하므로, 일반적으로는 완료 여부를 폴링하면 됩니다.

if (future.status() != firebase::kFutureStatusPending) {
  if (future.status() != firebase::kFutureStatusComplete) {
    LogMessage("ERROR: GetData() returned an invalid future.");
    // Handle the error...
  } else if (future.Error() != firebase::storage::kErrorNone) {
    LogMessage("ERROR: GetData() returned error %d: %s", future.Error(),
               future.error_message());
    // Handle the error...
    }
  } else {
    // Metadata contains file metadata such as size, content-type, and download URL.
    Metadata* metadata = future.Result();
    std::string download_url = metadata->download_url();
  }
}

로컬 파일에서 업로드

PutFile() 메서드를 사용하여 기기의 카메라에서 사진 및 동영상과 같은 로컬 파일을 업로드할 수 있습니다. PutFile()은 파일의 경로를 나타내는 std::string을 사용하며, Future가 완료되면 파일에 대한 정보를 포함하는 Future<Metadata>를 반환합니다. Controller를 사용하여 업로드를 관리하고 상태를 모니터링할 수 있습니다.

// File located on disk
std::string local_file = ...

// Create a reference to the file you want to upload
StorageReference rivers_ref = storage_ref.Child("images/rivers.jpg");

// Upload the file to the path "images/rivers.jpg"
Future future = rivers_ref.PutFile(localFile);

// Wait for Future to complete...

if (future.Error() != firebase::storage::kErrorNone) {
  // Uh-oh, an error occurred!
} else {
  // Metadata contains file metadata such as size, content-type, and download URL.
  Metadata* metadata = future.Result();
  std::string download_url = metadata->download_url();
}

업로드를 적극적으로 관리하려면 PutFile() 또는 PutBytes() 메서드에 Controller를 제공하면 됩니다. 이렇게 하면 컨트롤러를 사용하여 진행 중인 업로드 작업을 관찰할 수 있습니다. 자세한 내용은 업로드 관리를 참조하세요.

파일 메타데이터 추가

파일을 업로드할 때 메타데이터를 포함할 수도 있습니다. 이 메타데이터는 name, size, content_type(통칭 MIME 유형) 등의 일반적인 파일 메타데이터 속성을 포함합니다. PutFile() 메서드를 사용하면 파일 이름 확장자에서 콘텐츠 유형이 자동으로 추론되지만, 메타데이터에 content_type을 지정하면 자동 감지된 유형을 재정의할 수 있습니다. content_type을 지정하지 않았고 Cloud Storage가 파일 확장자에서 기본값을 추론할 수 없는 경우에는 Cloud Storageapplication/octet-stream을 사용합니다. 파일 메타데이터에 대한 자세한 내용은 파일 메타데이터 사용 섹션을 참고하세요.

// Create storage reference
StorageReference mountains_ref = storage_ref.Child("images/mountains.jpg");

// Create file metadata including the content type
StorageMetadata metadata;
metadata.set_content_type("image/jpeg");

// Upload data and metadata
mountains_ref.PutBytes(data, metadata);

// Upload file and metadata
mountains_ref.PutFile(local_file, metadata);

업로드 관리

업로드를 시작할 수 있을 뿐만 아니라, 선택적으로 PutBytes() 또는 PutFile() 메서드에 전달할 수 있는 ControllerPause(), Resume(), Cancel() 메서드를 사용하여 업로드를 일시 중지, 재개, 취소할 수 있습니다.

// Start uploading a file
firebase::storage::Controller controller;
storage_ref.Child("images/mountains.jpg").PutFile(local_file, nullptr, &controller);

// Pause the upload
controller.Pause();

// Resume the upload
controller.Resume();

// Cancel the upload
controller.Cancel();

업로드 진행률 모니터링

업로드에 리스너를 연결하여 업로드 진행률을 모니터링할 수 있습니다.

class MyListener : public firebase::storage::Listener {
 public:
  virtual void OnProgress(firebase::storage::Controller* controller) {
    // A progress event occurred
  }
};

{
  // Start uploading a file
  MyEventListener my_listener;
  storage_ref.Child("images/mountains.jpg").PutFile(local_file, my_listener);
}

오류 처리

업로드 시 로컬 파일이 없는 경우, 사용자에게 원하는 파일을 업로드할 권한이 없는 경우 등 다양한 이유로 오류가 발생할 수 있습니다. 오류의 자세한 내용은 문서의 오류 처리 섹션을 참조하세요.

다음 단계

이제 파일을 업로드했으니 Cloud Storage에서 파일을 다운로드하는 방법을 알아보겠습니다.