تحميل الملفات باستخدام Cloud Storage على Flutter

يتيح لك تطبيق "التخزين في السحابة الإلكترونية لبرنامج Firebase" تحميل الملفات بسرعة وسهولة إلى مجموعة بيانات Cloud Storage تقدّمها ويديرها Firebase.

تحميل ملفات

لتحميل ملف إلى Cloud Storage، عليك أولاً إنشاء إشارة إلى المسار الكامل للملف، بما في ذلك اسم الملف.

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

بعد إنشاء مرجع مناسب، يمكنك بعد ذلك استدعاء الأسلوب putFile() أو putString() أو putData() لتحميل الملف إلى Cloud Storage.

لا يمكنك تحميل بيانات تتضمّن إشارة إلى جذر حزمة Cloud Storage. يجب أن يشير المرجع إلى عنوان URL فرعي.

التحميل من ملف

لتحميل ملف، عليك أولاً الحصول على المسار المطلق لمكانه على الجهاز. على سبيل المثال، إذا كان هناك ملف ضمن directoryملفاتك في التطبيق، استخدِم حزمة path_provider الرسمية لإنشاء مسار ملف ونقله إلى 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) {
  // ...
}

التحميل من سلسلة

يمكنك تحميل البيانات كسلسلة برمجية غير مفسّرة أو مُشفَّرة بترميز base64 أو base64url أو data_url باستخدام طريقة putString(). على سبيل المثال، لتحميل سلسلة نصية تم ترميزها كعنوان URL للبيانات:

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

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

تحميل البيانات الأولية

يمكنك تحميل بيانات مكتوبة من المستوى الأدنى في شكل Uint8List في الحالات التي لا يكون فيها تحميل سلسلة أو File عمليًا. في هذه الحالة، يمكنك استدعاء طريقة putData() باستخدام بياناتك:

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

الحصول على عنوان URL للتنزيل

بعد تحميل ملف، يمكنك الحصول على عنوان URL لتنزيله من خلال استدعاء getDownloadUrl() على Reference:

await mountainsRef.getDownloadURL();

إضافة البيانات الوصفية للملف

يمكنك أيضًا تضمين البيانات الوصفية عند تحميل الملفات. تحتوي هذه البيانات الوصفية على سمات البيانات الوصفية المعتادة للملف، مثل contentType (المعروفة عادةً باسم نوع MIME). تستنتج طريقة putFile() تلقائيًا نوع MIME من الإضافة File، ولكن يمكنك تجاوز النوع الذي يتم رصده تلقائيًا من خلال تحديد contentType في البيانات الوصفية. إذا لم تقدِّم contentType ولم تتمكّن خدمة Cloud Storage من استنتاج قيمة تلقائية من امتداد الملف، ستستخدم Cloud Storage قيمة application/octet-stream. راجِع استخدام البيانات الوصفية للملف.

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

إدارة التحميلات

بالإضافة إلى بدء عمليات التحميل، يمكنك إيقافها مؤقتًا واستئنافها وإلغاؤها باستخدام methods pause() وresume() وcancel(). تؤدي أحداث الإيقاف المؤقت والاستئناف إلى تغيير حالة pause وprogress على التوالي. يؤدي إلغاء عملية carregar إلى تعذُّر التحميل مع ظهور خطأ يشير إلى أنّه تم إلغاء عملية carregar.

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

تتبُّع مستوى تقدُّم عملية التحميل

يمكنك الاستماع إلى أحداث مهمة معيّنة للتعامل مع حالات النجاح أو الفشل أو التقدّم أو الفواصل في مهمة التحميل:

نوع الحدث الاستخدام المعتاد
TaskState.running يتمّ بثّه بشكل دوري أثناء نقل البيانات ويمكن استخدامه لتعبئة مؤشر التحميل/التنزيل.
TaskState.paused يتمّ بثّه في أيّ وقت يتمّ فيه إيقاف المهمّة مؤقتًا.
TaskState.success يتمّ بثّه عند اكتمال المهمة بنجاح.
TaskState.canceled يتمّ بثّه في أيّ وقت يتمّ فيه إلغاء المهمة.
TaskState.error يتمّ بثّه عند تعذّر التحميل. ويمكن أن يحدث ذلك بسبب انتهاء مهلة الشبكة أو تعذُّر الحصول على إذن أو في حال إلغاء المهمة.
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;
  }
});

خطأ أثناء المعالجة

هناك عدد من الأسباب التي قد تؤدي إلى حدوث أخطاء أثناء التحميل، بما في ذلك عدم توفّر الملف على الجهاز أو عدم توفّر إذن لدى المستخدم لتحميل الملف المطلوب. يمكنك العثور على مزيد من المعلومات حول الأخطاء في القسم معالجة الأخطاء من المستندات.

مثال كامل

في ما يلي مثال كامل على عملية تحميل تتضمّن مراقبة مستوى التقدّم ومعالجة الأخطاء:

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

بعد تحميل الملفات، لنتعرّف على كيفية تنزيلها من Cloud Storage.