Faça upload de arquivos com Cloud Storage no Flutter

O Cloud Storage para Firebase permite fazer upload de arquivos de forma rápida e fácil para um bucket do Cloud Storage fornecido e gerenciado pelo Firebase.

Fazer upload de arquivos

Para fazer upload de um arquivo para o Cloud Storage, primeiro crie uma referência ao caminho completo do arquivo, incluindo o nome do arquivo.

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

Depois de criar uma referência apropriada, chame o método putFile() , putString() ou putData() para fazer upload do arquivo para o Cloud Storage.

Não é possível fazer upload de dados com referência à raiz do intervalo do Cloud Storage. Sua referência deve apontar para um URL filho.

Carregar de um arquivo

Para fazer upload de um arquivo, você deve primeiro obter o caminho absoluto para sua localização no dispositivo. Por exemplo, se existir um arquivo no diretório de documentos do aplicativo, use o pacote oficial path_provider para gerar um caminho de arquivo e passá-lo para 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) {
  // ...
}

Fazer upload de uma string

Você pode fazer upload de dados como uma string codificada base64 , base64url ou data_url usando o método putString() . Por exemplo, para fazer upload de uma string de texto codificada como URL de dados:

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

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

Fazendo upload de dados brutos

Você pode fazer upload de dados digitados de nível inferior na forma de Uint8List para aqueles casos em que o upload de uma string ou File não é prático. Neste caso, chame o método putData() com seus dados:

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

Obtenha um URL de download

Depois de fazer upload de um arquivo, você pode obter uma URL para fazer download do arquivo chamando o método getDownloadUrl() na Reference :

await mountainsRef.getDownloadURL();

Adicionar metadados de arquivo

Você também pode incluir metadados ao fazer upload de arquivos. Esses metadados contêm propriedades típicas de metadados de arquivo, como contentType (comumente chamado de tipo MIME). O método putFile() infere automaticamente o tipo MIME da extensão File , mas você pode substituir o tipo detectado automaticamente especificando contentType nos metadados. Se você não fornecer um contentType e o Cloud Storage não puder inferir um padrão da extensão do arquivo, o Cloud Storage usará application/octet-stream . Consulte Usar metadados de arquivo .

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

Gerenciar envios

Além de iniciar uploads, você pode pausar, retomar e cancelar uploads usando os métodos pause() , resume() e cancel() . Os eventos de pausa e retomada geram mudanças de estado pause e progress , respectivamente. Cancelar um upload faz com que ele falhe com um erro indicando que o upload foi cancelado.

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

Monitore o progresso do upload

Você pode ouvir o fluxo de eventos de uma tarefa para lidar com sucesso, falha, progresso ou pausas em sua tarefa de upload:

Tipo de evento Uso típico
TaskState.running Emitido periodicamente à medida que os dados são transferidos e pode ser usado para preencher um indicador de upload/download.
TaskState.paused Emitido sempre que a tarefa é pausada.
TaskState.success Emitido quando a tarefa foi concluída com êxito.
TaskState.canceled Emitido sempre que a tarefa é cancelada.
TaskState.error Emitido quando o upload falhou. Isso pode acontecer devido a tempos limite de rede, falhas de autorização ou se você cancelar a tarefa.
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;
  }
});

Manipulação de erros

Há vários motivos pelos quais podem ocorrer erros no upload, incluindo a inexistência do arquivo local ou o usuário não ter permissão para fazer upload do arquivo desejado. Você pode encontrar mais informações sobre erros na seção Tratar erros dos documentos.

Exemplo completo

Um exemplo completo de upload com monitoramento de progresso e tratamento de erros é mostrado abaixo:

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

Agora que você fez upload dos arquivos, vamos aprender como baixá-los do Cloud Storage.