Как загружать файлы в Cloud Storage с помощью Flutter

Cloud Storage for Firebase позволяет быстро и легко загружать файлы в сегмент Cloud Storage, предоставленный и управляемый Firebase.

Загрузка файлов

Чтобы загрузить файл в Cloud Storage, сначала создайте ссылку на полный путь к файлу, включая его название.

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

После того как вы создадите подходящую ссылку, вызовите метод putFile(), putString() или putData(), чтобы загрузить файл в Cloud Storage.

Нельзя загружать данные со ссылкой на корневой каталог сегмента Cloud Storage. Ссылка должна вести на дочерний URL.

Загрузка из файла

Чтобы загрузить файл, сначала нужно получить абсолютный путь к нему на устройстве. Например, если файл находится в каталоге документов приложения, используйте официальный пакет path_provider, чтобы создать путь к файлу и передать его в 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) {
  // ...
}

Загрузка из строки

Вы можете загрузить данные в виде необработанной строки, строки в кодировке base64, base64url или data_url, используя метод putString(). Например, чтобы загрузить текстовую строку, закодированную как URL данных:

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

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

Загрузка первичных данных

Вы можете загрузить типизированные данные более низкого уровня в форме Uint8List, если загрузка строки или File нецелесообразна. В этом случае вызовите метод putData() с вашими данными:

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

Как получить URL для скачивания

После загрузки файла вы можете получить URL для его скачивания, вызвав метод getDownloadUrl() для объекта Reference:

await mountainsRef.getDownloadURL();

Как добавить метаданные файла

При загрузке файлов можно также добавлять метаданные. Эти метаданные содержат стандартные свойства файлов, например contentType (обычно называемый MIME-типом). Метод putFile() автоматически определяет MIME-тип по расширению File, но вы можете переопределить автоматически определенный тип, указав contentType в метаданных. Если вы не укажете contentType, а Cloud Storage не сможет определить значение по умолчанию на основе расширения файла, будет использовано значение application/octet-stream. Подробнее об использовании метаданных файлов…

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

Управление загрузками

Помимо запуска загрузки, вы можете приостанавливать, возобновлять и отменять ее с помощью методов pause(), resume() и cancel(). События приостановки и возобновления вызывают изменения состояния pause и progress соответственно. Если отменить загрузку, она завершится с ошибкой, указывающей на то, что загрузка была отменена.

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

Как отслеживать ход загрузки

Вы можете прослушивать поток событий задачи, чтобы обрабатывать успешное выполнение, сбои, прогресс или паузы в задаче загрузки:

Тип события Типичное использование
TaskState.running Периодически передается по мере переноса данных и может использоваться для заполнения индикатора загрузки или скачивания.
TaskState.paused Событие, которое возникает при приостановке задачи.
TaskState.success Событие, которое возникает при успешном завершении задачи.
TaskState.canceled Срабатывает при отмене задачи.
TaskState.error Событие, которое возникает при сбое загрузки. Это может произойти из-за превышения времени ожидания сетевого подключения, сбоя авторизации или отмены задачи.
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;
  }
});

Обработка ошибок

При загрузке могут возникать ошибки по разным причинам, например из-за того, что локальный файл не существует или у пользователя нет разрешения на загрузку нужного файла. Дополнительную информацию об ошибках можно найти в разделе Обработка ошибок документации.

Полный пример

Ниже приведен полный пример загрузки с отслеживанием прогресса и обработкой ошибок:

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

Теперь, когда вы загрузили файлы, давайте узнаем, как скачать их из Cloud Storage.