Przesyłaj pliki za pomocą Cloud Storage na 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.

Prześlij pliki

Aby przesłać plik do Cloud Storage, najpierw utwórz odniesienie do pełnej ścieżki pliku, łącznie z nazwą pliku.

// 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łujesz 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. Twoje odwołanie musi wskazywać na podrzędny adres URL.

Prześlij z pliku

Aby przesłać plik, musisz najpierw uzyskać bezwzględną ścieżkę do jego lokalizacji na urządzeniu. Na przykład, jeśli plik istnieje w katalogu dokumentów aplikacji, użyj oficjalnego pakietu path_provider , 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) {
  // ...
}

Prześlij z ciągu

Możesz przesyłać dane jako ciąg znaków nieprzetworzony, zakodowany base64 , base64url lub data_url , korzystając z metody putString() . Na przykład, aby 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

Możesz przesłać wpisane dane niższego poziomu w formie listy Uint8List w przypadkach, gdy przesłanie ciągu znaków lub File nie jest praktyczne. W takim przypadku wywołaj metodę putData() ze swoimi danymi:

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

Uzyskaj adres URL pobierania

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

await mountainsRef.getDownloadURL();

Dodaj metadane pliku

Przesyłając pliki, możesz także dołączyć metadane. Te metadane zawierają typowe właściwości metadanych plików, takie jak contentType (powszechnie określany jako typ MIME). Metoda putFile() automatycznie wnioskuje typ MIME na podstawie rozszerzenia File , ale można zastąpić typ wykryty automatycznie, określając contentType w metadanych. Jeśli nie podasz contentType i Cloud Storage nie będzie mógł wywnioskować wartości domyślnej z rozszerzenia pliku, Cloud Storage użyje application/octet-stream . Zobacz Użyj 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() . Zdarzenia wstrzymywania i wznawiania powodują odpowiednio zmiany stanu pause i progress . Anulowanie przesyłania powoduje niepowodzenie przesyłania i wyświetlenie błędu wskazującego, ż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');

Monitoruj postęp przesyłania

Możesz odsłuchać strumień zdarzeń zadania, aby poradzić sobie z sukcesem, niepowodzeniem, postępem lub przerwami w zadaniu przesyłania:

Typ wydarzenia Typowe użycie
TaskState.running Emitowane okresowo podczas przesyłania danych. Można je wykorzystać do wypełnienia wskaźnika wysyłania/pobierania.
TaskState.paused Emitowane za każdym razem, gdy zadanie jest wstrzymane.
TaskState.success Emitowane po pomyślnym zakończeniu zadania.
TaskState.canceled Emitowane za każdym razem, gdy zadanie zostanie anulowane.
TaskState.error Emitowane, gdy przesyłanie nie powiodło się. 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

Istnieje wiele powodów, dla których mogą wystąpić błędy podczas przesyłania, na przykład nieistniejący plik lokalny lub brak uprawnień użytkownika do przesłania żądanego pliku. Więcej informacji na temat błędów można znaleźć w sekcji Obsługiwanie błędów w dokumentacji.

Pełny przykład

Pełny przykład przesyłania z monitorowaniem postępu i obsługą błędów pokazano poniżej:

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

Po przesłaniu plików nauczmy się, jak je pobrać z Cloud Storage.