Przesyłanie plików do Cloud Storage w Flutter

Cloud Storage dla Firebase umożliwia szybkie i łatwe przesyłanie plików do zasobnika Cloud Storage udostępnionego i zarządzanego przez Firebase.

Prześlij pliki

Aby przesłać plik do Cloud Storage, musisz najpierw utworzyć odwołanie do pełnej ścieżki do pliku, w tym jego nazwy.

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

Po utworzeniu odpowiedniego odwołania wywołujesz metodę putFile(), putString() lub putData(), aby przesłać plik do Cloud Storage.

Nie możesz przesyłać danych z odwołaniem do katalogu głównego zasobnika Cloud Storage. Odwoływanie musi wskazywać adres URL podrzędny.

Przesyłanie z pliku

Aby przesłać plik, musisz najpierw uzyskać ścieżkę bezwzględną do jego lokalizacji na urządzeniu. Jeśli na przykład plik znajduje się w katalogu dokumentów aplikacji, użyj oficjalnego pakietu path_provider, aby wygenerować ścieżkę do pliku i przekazać ją do funkcji 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) {
  // ...
}

Prześlij z ciągu

Dane możesz przesyłać w postaci nieprzetworzonego ciągu znaków, zakodowanego w formacie base64, base64url lub data_url, przy użyciu metody putString(). Aby np. przesłać ciąg tekstowy zakodowany jako URL danych:

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

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

Przesyłanie nieprzetworzonych danych

W przypadku, gdy przesyłanie ciągu znaków lub wartości File nie jest praktyczne, możesz przesłać dane typu niższy w postaci Uint8List. W tym przypadku wywołaj metodę putData() z danymi:

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

Uzyskiwanie adresu URL do pobrania

Po przesłaniu pliku możesz uzyskać adres URL do jego pobrania, wywołując metodę getDownloadUrl() w obiekcie Reference:

await mountainsRef.getDownloadURL();

Dodawanie metadanych pliku

Możesz też dołączyć metadane podczas przesyłania plików. Te metadane zawierają typowe właściwości metadanych pliku, takie jak contentType(zwykle określane jako typ MIME). Metoda putFile() automatycznie określa typ MIME na podstawie rozszerzenia File, ale możesz zastąpić ten wykryty automatycznie, określając w metadanych contentType. Jeśli nie podasz wartości contentType, a Cloud Storage nie będzie w stanie określić domyślnej wartości na podstawie rozszerzenia pliku, Cloud Storage użyje wartości application/octet-stream. Zobacz Używanie metadanych pliku.

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

Zarządzaj przesyłaniem

Oprócz rozpoczynania przesyłania możesz wstrzymywać, wznawiać i anulować przesyłanie, korzystając z metod pause(), resume() i cancel(). Wstrzymywanie i wznawianie działania odpowiednio pauseprogress. Anulowanie przesyłania spowoduje, że zakończy się ono niepowodzeniem i wyświetli się komunikat o błędzie informujący o tym, że przesyłanie zostało anulowane.

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

Monitorowanie postępu przesyłania

Możesz słuchać strumienia zdarzeń zadania, aby obsłużyć powodzenie, niepowodzenie, postęp lub przerwy w zadaniu przesyłania:

Typ zdarzenia Typowe zastosowanie
TaskState.running Jest wysyłany okresowo podczas przesyłania danych i może służyć do wypełniania wskaźnika przesyłania/pobierania.
TaskState.paused Emitowany za każdym razem, gdy zadanie jest wstrzymane.
TaskState.success Emitowany po pomyślnym zakończeniu zadania.
TaskState.canceled Emitowany za każdym razem, gdy zadanie zostanie anulowane.
TaskState.error Występuje, gdy przesyłanie się nie powiodło. Może się to zdarzyć z powodu przerw w dostępie do sieci, błędów autoryzacji lub anulowania zadania.
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;
  }
});

Obsługa błędów

Błędy mogą wystąpić z kilku powodów podczas przesyłania. Mogą one dotyczyć nieistniejącego pliku lokalnego lub braku uprawnień użytkownika do przesłania żądanego pliku. Więcej informacji o błędach znajdziesz w sekcji Przetwarzanie błędów w dokumentacji.

Pełny przykład

Poniżej przedstawiamy pełny przykład przesyłania z monitorowaniem postępu i obsługą błędów:

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

Teraz, gdy pliki zostały przesłane, dowiedz się, jak je pobrać z Cloud Storage.