Sube archivos con Cloud Storage en Flutter

Cloud Storage para Firebase le permite cargar archivos de forma rápida y sencilla a un depósito de Cloud Storage proporcionado y administrado por Firebase.

Subir archivos

Para cargar un archivo en Cloud Storage, primero crea una referencia a la ruta completa del archivo, incluido el nombre del archivo.

// Create a storage reference from our app
final storageRef = FirebaseStorage.instance.ref();

// Create a reference to "mountains.jpg"
final mountainsRef = storageRef.child("mountains.jpg");

// Create a reference to 'images/mountains.jpg'
final mountainImagesRef = storageRef.child("images/mountains.jpg");

// While the file names are the same, the references point to different files
assert(mountainsRef.name == mountainImagesRef.name);
assert(mountainsRef.fullPath != mountainImagesRef.fullPath);

Una vez que haya creado una referencia adecuada, llame al método putFile() , putString() o putData() para cargar el archivo en Cloud Storage.

No puedes cargar datos con una referencia a la raíz de tu depósito de Cloud Storage. Su referencia debe apuntar a una URL secundaria.

Subir desde un archivo

Para cargar un archivo, primero debe obtener la ruta absoluta a su ubicación en el dispositivo. Por ejemplo, si existe un archivo dentro del directorio de documentos de la aplicación, use el paquete oficial path_provider para generar una ruta de archivo y pásela a putFile() :

Directory appDocDir = await getApplicationDocumentsDirectory();
String filePath = '${appDocDir.absolute}/file-to-upload.png';
File file = File(filePath);

try {
  await mountainsRef.putFile(file);
} on firebase_core.FirebaseException catch (e) {
  // ...
}

Subir desde una cadena

Puede cargar datos como una cadena codificada base64 , base64url o data_url utilizando el método putString() . Por ejemplo, para cargar una cadena de texto codificada como URL de datos:

String dataUrl = 'data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==';

try {
  await mountainsRef.putString(dataUrl, format: PutStringFormat.dataUrl);
} on FirebaseException catch (e) {
  // ...
}

Cargando datos sin procesar

Puede cargar datos escritos de nivel inferior en forma de Uint8List para aquellos casos en los que cargar una cadena o File no sea práctico. En este caso, llama al método putData() con tus datos:

try {
  // Upload raw data.
  await mountainsRef.putData(data);
} on firebase_core.FirebaseException catch (e) {
  // ...
}

Obtener una URL de descarga

Después de cargar un archivo, puede obtener una URL para descargar el archivo llamando al método getDownloadUrl() en la Reference :

await mountainsRef.getDownloadURL();

Agregar metadatos de archivo

También puedes incluir metadatos cuando subes archivos. Estos metadatos contienen propiedades típicas de metadatos de archivos, como contentType (comúnmente conocido como tipo MIME). El método putFile() infiere automáticamente el tipo MIME a partir de la extensión File , pero puede anular el tipo detectado automáticamente especificando contentType en los metadatos. Si no proporciona un contentType y Cloud Storage no puede inferir un valor predeterminado a partir de la extensión del archivo, Cloud Storage usa application/octet-stream . Consulte Usar metadatos de archivos .

try {
  await mountainsRef.putFile(file, SettableMetadata(
    contentType: "image/jpeg",
  ));
} on firebase_core.FirebaseException catch (e) {
  // ...
}

Administrar cargas

Además de iniciar las cargas, puede pausarlas, reanudarlas y cancelarlas utilizando los métodos pause() , resume() y cancel() . Los eventos de pausa y reanudación generan cambios de estado pause y progress respectivamente. Cancelar una carga hace que la carga falle con un error que indica que la carga fue cancelada.

final task = mountainsRef.putFile(largeFile);

// Pause the upload.
bool paused = await task.pause();
print('paused, $paused');

// Resume the upload.
bool resumed = await task.resume();
print('resumed, $resumed');

// Cancel the upload.
bool canceled = await task.cancel();
print('canceled, $canceled');

Supervisar el progreso de la carga

Puedes escuchar el flujo de eventos de una tarea para controlar el éxito, el fracaso, el progreso o las pausas en tu tarea de carga:

Tipo de evento Uso típico
TaskState.running Se emite periódicamente a medida que se transfieren datos y se puede utilizar para completar un indicador de carga/descarga.
TaskState.paused Se emite cada vez que se pausa la tarea.
TaskState.success Emitido cuando la tarea se ha completado con éxito.
TaskState.canceled Se emite cada vez que se cancela la tarea.
TaskState.error Emitido cuando la carga ha fallado. Esto puede suceder debido a tiempos de espera de la red, fallas de autorización o si cancela la tarea.
mountainsRef.putFile(file).snapshotEvents.listen((taskSnapshot) {
  switch (taskSnapshot.state) {
    case TaskState.running:
      // ...
      break;
    case TaskState.paused:
      // ...
      break;
    case TaskState.success:
      // ...
      break;
    case TaskState.canceled:
      // ...
      break;
    case TaskState.error:
      // ...
      break;
  }
});

Manejo de errores

Hay varias razones por las que pueden ocurrir errores durante la carga, incluido el archivo local que no existe o que el usuario no tiene permiso para cargar el archivo deseado. Puede encontrar más información sobre los errores en la sección Manejar errores de los documentos.

Ejemplo completo

A continuación se muestra un ejemplo completo de una carga con seguimiento del progreso y manejo de errores:

final appDocDir = await getApplicationDocumentsDirectory();
final filePath = "${appDocDir.absolute}/path/to/mountains.jpg";
final file = File(filePath);

// Create the file metadata
final metadata = SettableMetadata(contentType: "image/jpeg");

// Create a reference to the Firebase Storage bucket
final storageRef = FirebaseStorage.instance.ref();

// Upload file and metadata to the path 'images/mountains.jpg'
final uploadTask = storageRef
    .child("images/path/to/mountains.jpg")
    .putFile(file, metadata);

// Listen for state changes, errors, and completion of the upload.
uploadTask.snapshotEvents.listen((TaskSnapshot taskSnapshot) {
  switch (taskSnapshot.state) {
    case TaskState.running:
      final progress =
          100.0 * (taskSnapshot.bytesTransferred / taskSnapshot.totalBytes);
      print("Upload is $progress% complete.");
      break;
    case TaskState.paused:
      print("Upload is paused.");
      break;
    case TaskState.canceled:
      print("Upload was canceled");
      break;
    case TaskState.error:
      // Handle unsuccessful uploads
      break;
    case TaskState.success:
      // Handle successful uploads on complete
      // ...
      break;
  }
});

Ahora que has subido archivos, aprendamos cómo descargarlos desde Cloud Storage.