Descarga archivos con Cloud Storage en Flutter

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

Crea una referencia

Para descargar un archivo, primero crea una referencia de Cloud Storage al archivo que deseas descargar.

Para ello, puedes adjuntar rutas de acceso secundarias a la raíz de tu bucket de Cloud Storage o puedes crear una referencia a partir de una URL gs:// o https:// existente que haga referencia a un objeto en Cloud Storage.

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

// Create a reference with an initial file path and name
final pathReference = storageRef.child("images/stars.jpg");

// Create a reference to a file from a Google Cloud Storage URI
final gsReference =
    FirebaseStorage.instance.refFromURL("gs://YOUR_BUCKET/images/stars.jpg");

// Create a reference from an HTTPS URL
// Note that in the URL, characters are URL escaped!
final httpsReference = FirebaseStorage.instance.refFromURL(
    "https://firebasestorage.googleapis.com/b/YOUR_BUCKET/o/images%20stars.jpg");

Descarga archivos

Cuando tengas una referencia, puedes descargar archivos desde Cloud Storage con una llamada a getData() o getStream(). Si prefieres descargar el archivo con otra biblioteca, puedes obtener una URL de descarga con getDownloadUrl().

Descarga en la memoria

Descarga el archivo a un UInt8List con el método getData(). Esta es la forma más fácil de descargar un archivo, pero requiere cargar todo su contenido en la memoria. Si solicitas un archivo más grande que la memoria disponible para tu app, esta fallará. Para brindar protección contra los problemas de memoria, getData() necesita una cantidad máxima de bytes para descargar. Establece el tamaño máximo con un valor que sepas que la app pueda controlar o usa otro método de descarga.

final islandRef = storageRef.child("images/island.jpg");

try {
  const oneMegabyte = 1024 * 1024;
  final Uint8List? data = await islandRef.getData(oneMegabyte);
  // Data for "images/island.jpg" is returned, use this as needed.
} on FirebaseException catch (e) {
  // Handle any errors.
}

Descarga en un archivo local

El método writeToFile() permite descargar un archivo directamente en un dispositivo local. Úsalo si tus usuarios quieren tener acceso al archivo sin conexión o para compartir el archivo en una app diferente. writeToFile() muestra un DownloadTask que puedes usar para administrar la descarga y supervisar su estado.

final islandRef = storageRef.child("images/island.jpg");

final appDocDir = await getApplicationDocumentsDirectory();
final filePath = "${appDocDir.absolute}/images/island.jpg";
final file = File(filePath);

final downloadTask = islandRef.writeToFile(file);
downloadTask.snapshotEvents.listen((taskSnapshot) {
  switch (taskSnapshot.state) {
    case TaskState.running:
      // TODO: Handle this case.
      break;
    case TaskState.paused:
      // TODO: Handle this case.
      break;
    case TaskState.success:
      // TODO: Handle this case.
      break;
    case TaskState.canceled:
      // TODO: Handle this case.
      break;
    case TaskState.error:
      // TODO: Handle this case.
      break;
  }
});

Descarga datos a través de URL

Si ya tienes una infraestructura de descarga basada en URLs o simplemente quieres una URL para compartir, puedes llamar al método getDownloadURL() en una referencia de Cloud Storage a fin de obtener la URL de descarga de un archivo.

final imageUrl =
    await storageRef.child("users/me/profile.png").getDownloadURL();

Soluciona errores

Existen varios motivos por los cuales se pueden producir errores durante una descarga; por ejemplo, es posible que el archivo no exista o que el usuario no tenga permiso para acceder al archivo deseado. Para obtener más información sobre los errores, consulta la sección de los documentos denominada Soluciona errores.

Ejemplo completo

A continuación, se muestra un ejemplo completo de una descarga con solución de errores:

final islandRef = storageRef.child("images/island.jpg");

final appDocDir = await getApplicationDocumentsDirectory();
final filePath = "${appDocDir.absolute}/images/island.jpg";
final file = File(filePath);

final downloadTask = islandRef.writeToFile(file);
downloadTask.snapshotEvents.listen((taskSnapshot) {
  switch (taskSnapshot.state) {
    case TaskState.running:
      // TODO: Handle this case.
      break;
    case TaskState.paused:
      // TODO: Handle this case.
      break;
    case TaskState.success:
      // TODO: Handle this case.
      break;
    case TaskState.canceled:
      // TODO: Handle this case.
      break;
    case TaskState.error:
      // TODO: Handle this case.
      break;
  }
});

También puedes obtener y actualizar metadatos para los archivos almacenados en Cloud Storage.