Sube archivos con Cloud Storage para C++

Cloud Storage para Firebase te permite subir archivos con rapidez y facilidad a un bucket de Cloud Storage proporcionado y administrado por Firebase.

Crea una referencia

Para subir un archivo, primero crea una referencia de Cloud Storage a la ubicación de Cloud Storage a la que deseas subir el archivo.

Para ello, puedes anexar rutas de acceso secundarias a la raíz de tu bucket de Cloud Storage, como se indica a continuación:

// 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

No puedes subir datos con una referencia a la raíz del bucket de Google Cloud Storage. La referencia debe apuntar a una URL secundaria.

Sube archivos

Una vez que tengas una referencia, puedes subir archivos a Cloud Storage de dos maneras:

  1. subir desde un búfer de bytes en la memoria
  2. subir desde una ruta de archivo que represente un archivo en el dispositivo

Sube archivos desde datos en la memoria

El método PutData() es la forma más simple de subir un archivo a Cloud Storage. PutData() recibe un búfer de bytes y arroja un Future<Metadata>, que contendrá información acerca del archivo cuando Future se complete. Puedes usar un Controller para administrar y supervisar el estado de la carga.

// 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);

En este momento, la solicitud ya se hizo, pero tenemos que esperar a que se complete Future antes de que se suba el archivo. Dado que los juegos tienden a ejecutarse en bucle y usan menos devoluciones de llamadas que otras aplicaciones, lo normal es hacer un sondeo para determinar si se completó la operación.

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();
  }
}

Sube archivos desde un archivo local

Puedes usar el método PutFile() para subir archivos locales de los dispositivos, como fotos y videos de la cámara. PutFile() toma una std::string que representa la ruta al archivo y muestra un Future<Metadata>, que contendrá información sobre el archivo cuando se complete la interfaz Future. Puedes usar un Controller para administrar y supervisar el estado de la carga.

// 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();
}

Si deseas administrar la carga de forma activa, puedes proporcionar un Controller a los métodos PutFile() o PutBytes(). De esta manera, puedes usar el controlador para observar la operación de carga en curso. Consulta cómo administrar cargas para obtener más información.

Agrega metadatos de archivos

También puedes incluir metadatos cuando subas archivos. Estos metadatos contienen propiedades típicas de metadatos de archivo, como name, size y content_type (comúnmente denominadas tipos de MIME). El método PutFile() infiere el tipo de contenido a partir de la extensión de nombre de archivo en forma automática, pero puedes especificar content_type en los metadatos para anular el tipo detectado. Si no proporcionas un content_type y Cloud Storage no puede inferir un tipo predeterminado a partir de una extensión de archivo, Cloud Storage usará application/octet-stream. Consulta la sección Usa metadatos de archivo para obtener más información acerca de estos.

// 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);

Administra cargas

Además de iniciar cargas, puedes detenerlas, reanudarlas y cancelarlas con los métodos Pause(), Resume() y Cancel() en Controller, que pueden pasarse a los métodos PutBytes() o PutFile() de manera opcional.

// 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();

Supervisa el progreso de la carga

Puedes adjuntar agentes de escucha a las cargas para supervisar su progreso.

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);
}

Manejo de errores

Existen diferentes motivos por los que pueden producirse errores durante la carga, como que el archivo local no exista o que el usuario no tenga permiso para subir el archivo deseado. Para obtener más información sobre los errores, consulta la sección de los documentos denominada Soluciona errores.

Próximos pasos

Ahora que ya subiste archivos, veamos cómo descargarlos de Cloud Storage.