Mengupload file dengan Cloud Storage di Flutter

Dengan Cloud Storage for Firebase, Anda dapat mengupload file dengan cepat dan mudah ke bucket Cloud Storage yang disediakan dan dikelola oleh Firebase.

Mengupload File

Untuk mengupload file ke Cloud Storage, buat referensi ke jalur lengkap file terlebih dahulu, termasuk nama filenya.

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

Setelah Anda membuat referensi yang sesuai, panggil metode putFile(), putString(), atau putData() untuk mengupload file ke Cloud Storage.

Anda tidak dapat mengupload data dengan referensi ke root bucket Cloud Storage. Referensi Anda harus mengarah ke URL turunan.

Mengupload dari file

Untuk mengupload file, Anda harus terlebih dahulu mendapatkan jalur absolut ke lokasi di perangkatnya. Misalnya, jika suatu file ada dalam direktori dokumen aplikasi, gunakan paket resmi path_provider untuk menghasilkan jalur file dan meneruskannya ke 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) {
  // ...
}

Mengupload dari String

Anda dapat mengupload data sebagai string berenkode base64, base64url, atau data_url mentah menggunakan metode putString(). Misalnya, untuk mengupload string teks yang dienkode sebagai URL Data:

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

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

Mengupload data mentah

Anda dapat mengupload data dengan jenis level yang lebih rendah dalam format Uint8List untuk kasus yang tidak praktis saat mengupload string atau File. Dalam hal ini, panggil metode putData() dengan data Anda:

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

Mendapatkan URL download

Setelah mengupload file, Anda bisa mendapatkan URL untuk mendownload file tersebut dengan memanggil metode getDownloadUrl() pada Reference:

await mountainsRef.getDownloadURL();

Menambahkan Metadata File

Anda juga dapat menyertakan metadata ketika mengupload file. Metadata ini berisi properti metadata file standar, seperti contentType (umumnya dikenal sebagai jenis MIME). Metode putFile() secara otomatis menyimpulkan jenis MIME dari ekstensi File, tetapi Anda bisa mengganti jenis yang terdeteksi otomatis dengan menetapkan contentType pada metadata. Jika contentType tidak ada dan Cloud Storage tidak dapat menyimpulkan default dari ekstensi file, Cloud Storage akan menggunakan application/octet-stream. Lihat Menggunakan Metadata File.

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

Mengelola Upload

Selain memulai upload, Anda dapat menjeda, melanjutkan, dan membatalkan upload menggunakan metode pause(), resume(), dan cancel(). Peristiwa jeda menyebabkan perubahan status pause dan peristiwa lanjutkan menyebabkan perubahan status progress. Jika dibatalkan, upload akan gagal dengan pesan error yang menunjukkan bahwa upload telah dibatalkan.

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

Memantau Progres Upload

Anda dapat memproses streaming peristiwa tugas untuk menangani keberhasilan, kegagalan, progres, atau jeda dalam tugas upload:

Jenis Peristiwa Penggunaan Standar
TaskState.running Dikeluarkan secara berkala saat data ditransfer dan dapat digunakan untuk mengisi indikator upload/download.
TaskState.paused Dikeluarkan setiap kali tugas dijeda.
TaskState.success Dikeluarkan saat tugas berhasil diselesaikan.
TaskState.canceled Dikeluarkan setiap kali tugas dibatalkan.
TaskState.error Dikeluarkan saat upload gagal. Hal ini dapat terjadi karena waktu tunggu jaringan habis, kegagalan otorisasi, atau jika Anda membatalkan tugas.
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;
  }
});

Penanganan Error

Ada sejumlah alasan penyebab terjadinya error saat upload, termasuk tidak adanya file lokal, atau pengguna tidak memiliki izin untuk mengupload file yang diinginkan. Anda dapat menemukan informasi lebih lanjut tentang error di bagian Menangani Error pada dokumentasi.

Contoh Lengkap

Contoh lengkap upload dengan pemantauan progres dan penanganan error ditampilkan di bawah ini:

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

Setelah mengupload file, pelajari cara mendownloadnya dari Cloud Storage.