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ępnianego i zarządzanego przez Firebase.

Przesyłanie plików

Aby przesłać plik do Cloud Storage, musisz najpierw utworzyć odniesienie do pełnej ścieżki 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 odniesienia wywołaj metodę putFile(), putString() lub putData(), aby przesłać plik do Cloud Storage.

Nie możesz przesyłać danych z odniesieniem do katalogu głównego zasobnika Cloud Storage. Odniesienie musi wskazywać adres URL elementu podrzędnego.

Przesyłanie z pliku

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

Przesyłanie z ciągu znaków

Za pomocą metody putString() możesz przesyłać dane jako ciąg znaków zakodowany w formacie base64, base64url lub data_url albo w postaci surowej. Aby na przykład przesłać ciąg tekstowy zakodowany jako adres URL danych:

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

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

Przesyłanie surowych danych

W przypadkach, gdy przesyłanie ciągu znaków lub File jest niepraktyczne, możesz przesyłać dane typowe niższego poziomu w postaci Uint8List. W takim przypadku wywołaj metodę putData() z danymi:

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

Pobieranie adresu URL pobierania

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

await mountainsRef.getDownloadURL();

Dodawanie metadanych pliku

Podczas przesyłania plików możesz też dołączyć metadane. Zawierają one typowe właściwości metadanych pliku, takie jak contentType (zwykle nazywany typem MIME). Metoda putFile() automatycznie wnioskuje typ MIME z rozszerzenia File, ale możesz zastąpić automatycznie wykryty typ, określając contentType w metadanych. Jeśli nie podasz contentType, a Cloud Storage nie będzie w stanie wywnioskować domyślnego typu z rozszerzenia pliku, Cloud Storage użyje application/octet-stream. Więcej informacji znajdziesz w artykule Używanie metadanych pliku.

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

Zarządzanie przesyłaniem

Oprócz rozpoczynania przesyłania możesz je wstrzymywać, wznawiać i anulować za pomocą metod pause(), resume() i cancel(). Zdarzenia wstrzymania i wznowienia powodują odpowiednio zmiany stanu pause i progress. Anulowanie przesyłania powoduje jego niepowodzenie z błędem wskazującym, że zostało ono 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

Aby obsługiwać powodzenie, niepowodzenie, postęp lub wstrzymanie zadania przesyłania, możesz nasłuchiwać strumienia zdarzeń zadania:

Typ zdarzenia Typowe zastosowanie
TaskState.running Emitowane okresowo podczas przesyłania danych. Można ich używać do wypełniania wskaźnika przesyłania/pobierania.
TaskState.paused Emitowane za każdym razem, gdy zadanie jest wstrzymywane.
TaskState.success Emitowane po pomyślnym zakończeniu zadania.
TaskState.canceled Emitowane za każdym razem, gdy zadanie jest anulowane.
TaskState.error Emitowane, gdy przesyłanie się nie powiedzie. Może się to zdarzyć z powodu przekroczenia limitu czasu 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 podczas przesyłania mogą wystąpić z różnych powodów, m.in. z powodu braku pliku lokalnego lub braku uprawnień użytkownika do przesłania wybranego pliku. Więcej informacji o błędach znajdziesz w sekcji Obsługa błędów w dokumentacji.

Pełny przykład

Poniżej znajdziesz 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 już wiesz, jak przesyłać pliki, dowiedz się, jak je pobierać z Cloud Storage.