تحميل الملفات باستخدام 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 فرعي.

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

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

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

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

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.