C++용 Cloud Storage로 파일 다운로드

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

참조 만들기

파일을 다운로드하려면 먼저 다운로드할 파일에 대한 Cloud Storage 참조를 만들어야 합니다.

Cloud Storage 버킷의 루트에 하위 경로를 추가하여 참조를 만들거나 Cloud Storage의 객체를 참조하는 기존 gs:// 또는 https:// URL에서 참조를 만들 수 있습니다.

// Create a reference with an initial file path and name
StorageReference path_reference = storage->GetReference("images/stars.jpg");

// Create a reference from a Cloud Storage URI
StorageReference gs_reference = storage->GetReferenceFromUrl("gs://bucket/images/stars.jpg");

// Create a reference from an HTTPS URL
// Note that in the URL, characters are URL escaped!
StorageReference https_reference = storage->GetReferenceFromUrl("https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg");

파일 다운로드

참조를 만들었으면 다음 세 가지 방법으로 Cloud Storage에서 파일을 다운로드할 수 있습니다.

  1. 메모리의 버퍼로 다운로드
  2. 기기의 특정 경로로 다운로드
  3. 온라인의 파일을 나타내는 문자열 URL 생성

메모리에 다운로드

GetBytes() 메서드를 사용하여 파일을 메모리의 바이트 버퍼로 다운로드합니다. 이는 파일을 빠르게 다운로드하는 가장 쉬운 방법이지만 메모리에 전체 파일 내용을 로드해야 합니다. 따라서 앱의 가용 메모리보다 큰 파일을 요청하면 앱이 다운됩니다. 메모리 문제를 방지하려면 최대 크기를 앱에서 처리할 수 있는 크기로 설정하거나 다른 다운로드 방법을 사용하세요.

// Create a reference to the file you want to download
StorageReference island_ref = storage_ref.Child("images/island.jpg");

// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
const size_t kMaxAllowedSize = 1 * 1024 * 1024
int8_t byte_buffer[kMaxAllowedSize];
firebase::Future<size_t> future = island_ref.GetBytes(byte_buffer, kMaxAllowedSize);

현재는 요청은 전송되었지만 Future가 완료되기를 기다려야 파일을 읽을 수 있는 상태입니다. 게임은 대개 루프로 실행되고 다른 애플리케이션보다 콜백에 덜 의존하므로, 일반적으로는 완료 여부를 단순히 조사하면 됩니다.

// In the game loop that polls for the result...

if (future.status() != firebase::kFutureStatusPending) {
  if (future.status() != firebase::kFutureStatusComplete) {
    LogMessage("ERROR: GetBytes() returned an invalid future.");
    // Handle the error...
  } else if (future.Error() != firebase::storage::kErrorNone) {
    LogMessage("ERROR: GetBytes() returned error %d: %s", future.Error(),
               future.error_message());
    // Handle the error...
  } else {
    // byte_buffer is now populated with data for "images/island.jpg"
  }
}

로컬 파일로 다운로드

GetFile() 메서드는 파일을 로컬 기기로 직접 다운로드합니다. 사용자가 오프라인 상태에서도 파일에 액세스해야 하거나 다른 앱에서 파일을 공유해야 하는 경우 이 방법을 사용하세요.

// Create a reference to the file you want to download
StorageReference islandRef = storage_ref.Child("images/island.jpg"];

// Create local filesystem URL
const char* local_url = "file:///local/images/island.jpg";

// Download to the local filesystem
Future<size_t> future = islandRef.GetFile(local_url);

// Wait for Future to complete...

if (future.Error() != firebase::storage::kErrorNone) {
  // Uh-oh, an error occurred!
} else {
  // The file has been downloaded to local file URL "images/island.jpg"
}

GetFile()는 선택사항으로 다운로드를 관리하는 데 사용할 수 있는 Controller 인수를 사용합니다. 자세한 내용은 다운로드 관리를 참조하세요.

다운로드 URL 생성

URL 기반 다운로드 인프라를 갖추고 있거나 단순히 URL을 공유하려는 경우 Cloud Storage 참조에 GetDownloadUrl() 메서드를 호출하여 파일의 다운로드 URL을 가져올 수 있습니다.

// Create a reference to the file you want to download
StorageReference stars_ref = storage_ref.Child("images/stars.jpg");

// Fetch the download URL
firebase::Future<std::string> future = stars_ref.GetDownloadUrl();

// Wait for Future to complete...

if (future.Error() != firebase::storage::kErrorNone) {
  // Uh-oh, an error occurred!
} else {
  // Get the download URL for 'images/stars.jpg'
  std::string download_url = future.Result();
}

다운로드 관리

다운로드를 시작할 수 있을 뿐만 아니라 GetBytes() 또는 GetFile() 메서드에 선택사항으로 전달할 수 있는 Controller에서 Pause(), Resume(), Cancel() 메서드를 사용하여 다운로드를 일시 중지, 재개, 취소할 수 있습니다.

// Start downloading a file
Controller controller;
storage_ref.Child("images/mountains.jpg").GetFile(local_file, nullptr, &controller);

// Pause the download
controller.Pause();

// Resume the download
controller.Resume();

// Cancel the download
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").GetFile(local_file, my_listener);
}

오류 처리

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

다음 단계

Cloud Storage에 저장된 파일의 메타데이터를 가져와서 업데이트할 수도 있습니다.