تحميل ملفات باستخدام Cloud Storage لـ C++

تتيح لك أداة Cloud Storage for Firebase تحميل الملفات بسرعة وسهولة إلى حزمة Cloud Storage التي توفّرها وتديرها منصة Firebase.

إنشاء مرجع

لتحميل ملف، عليك أولاً إنشاء مرجع Cloud Storage للموقع في Cloud Storage الذي تريد تحميل الملف إليه.

يمكنك إنشاء مرجع من خلال إلحاق مسارات فرعية بجذر حزمة Cloud Storage:

// Create a root reference
StorageReference storage_ref = storage->GetReference();

// Create a reference to "mountains.jpg"
StorageReference mountains_ref = storage_ref.Child("mountains.jpg");

// Create a reference to 'images/mountains.jpg'
StorageReference mountain_images_ref = storage_ref.Child("images/mountains.jpg");

// While the file names are the same, the references point to different files
mountains_ref.name() == mountain_images_ref.name();           // true
mountains_ref.full_path() == mountain_images_ref.full_path(); // false

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

تحميل ملفات

بعد الحصول على مرجع، يمكنك تحميل الملفات إلى Cloud Storage بطريقتَين:

  1. التحميل من مخزن بايت مؤقت في الذاكرة
  2. التحميل من مسار ملف يمثّل ملفًا على الجهاز

التحميل من البيانات في الذاكرة

تُعدّ طريقة PutData() أبسط طريقة لتحميل ملف إلى Cloud Storage. تأخذ الدالة PutData() مخزنًا مؤقتًا للبايت وتُرجع Future<Metadata> الذي سيحتوي على معلومات عن الملف عند اكتمال Future. يمكنك استخدام Controller لإدارة عملية التحميل ومراقبة حالتها.

// Data in memory
const size_t kByteBufferSize = ...
uint8_t byte_buffer[kByteBufferSize] = { ... };

// Create a reference to the file you want to upload
StorageReference rivers_ref = storage_ref.Child("images/rivers.jpg");

// Upload the file to the path "images/rivers.jpg"
Future future = rivers_ref.PutBytes(byte_buffer, kByteBufferSize);

في هذه المرحلة، تم تقديم الطلب ولكن علينا انتظار اكتمال Future قبل تحميل الملف. بما أنّ الألعاب تعمل عادةً في حلقة تكرار، وتعتمد على عمليات الاستدعاء بشكل أقل من التطبيقات الأخرى، ستستعلم عادةً عن اكتمال العملية.

if (future.status() != firebase::kFutureStatusPending) {
  if (future.status() != firebase::kFutureStatusComplete) {
    LogMessage("ERROR: GetData() returned an invalid future.");
    // Handle the error...
  } else if (future.Error() != firebase::storage::kErrorNone) {
    LogMessage("ERROR: GetData() returned error %d: %s", future.Error(),
               future.error_message());
    // Handle the error...
    }
  } else {
    // Metadata contains file metadata such as size, content-type, and download URL.
    Metadata* metadata = future.Result();
    std::string download_url = metadata->download_url();
  }
}

التحميل من ملف على الجهاز

يمكنك تحميل الملفات المحلية على الأجهزة، مثل الصور والفيديوهات من الكاميرا، باستخدام طريقة PutFile(). تأخذ الدالة PutFile() مَعلمة std::string تمثّل مسار الملف وتُرجع Future<Metadata> يحتوي على معلومات عن الملف عند اكتمال الكائن Future. يمكنك استخدام Controller لإدارة عملية التحميل ومراقبة حالتها.

// File located on disk
std::string local_file = ...

// Create a reference to the file you want to upload
StorageReference rivers_ref = storage_ref.Child("images/rivers.jpg");

// Upload the file to the path "images/rivers.jpg"
Future future = rivers_ref.PutFile(localFile);

// Wait for Future to complete...

if (future.Error() != firebase::storage::kErrorNone) {
  // Uh-oh, an error occurred!
} else {
  // Metadata contains file metadata such as size, content-type, and download URL.
  Metadata* metadata = future.Result();
  std::string download_url = metadata->download_url();
}

إذا أردت إدارة عملية التحميل بشكل نشط، يمكنك تقديم Controller إلى الطريقتَين PutFile() أو PutBytes(). يتيح لك ذلك استخدام وحدة التحكّم لمراقبة عملية التحميل الجارية. لمزيد من المعلومات، يُرجى الاطّلاع على إدارة عمليات التحميل.

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

يمكنك أيضًا تضمين بيانات وصفية عند تحميل الملفات. تحتوي هذه البيانات الوصفية على سمات البيانات الوصفية المعتادة للملفات، مثل name وsize وcontent_type (يُشار إليها عادةً باسم نوع MIME). تستنتج طريقة PutFile() نوع المحتوى تلقائيًا من امتداد اسم الملف، ولكن يمكنك إلغاء النوع الذي تم رصده تلقائيًا من خلال تحديد content_type في البيانات الوصفية. إذا لم تقدّم content_type ولم يتمكّن Cloud Storage من استنتاج قيمة تلقائية من امتداد الملف، يستخدم Cloud Storage السمة application/octet-stream. يمكنك الاطّلاع على قسم استخدام البيانات الوصفية للملفات لمزيد من المعلومات حول البيانات الوصفية للملفات.

// Create storage reference
StorageReference mountains_ref = storage_ref.Child("images/mountains.jpg");

// Create file metadata including the content type
StorageMetadata metadata;
metadata.set_content_type("image/jpeg");

// Upload data and metadata
mountains_ref.PutBytes(data, metadata);

// Upload file and metadata
mountains_ref.PutFile(local_file, metadata);

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

بالإضافة إلى بدء عمليات التحميل، يمكنك إيقافها مؤقتًا واستئنافها وإلغاؤها باستخدام الطرق Pause() وResume() وCancel() في Controller، والتي يمكنك تمريرها اختياريًا إلى الطرق PutBytes() أو PutFile().

// Start uploading a file
firebase::storage::Controller controller;
storage_ref.Child("images/mountains.jpg").PutFile(local_file, nullptr, &controller);

// Pause the upload
controller.Pause();

// Resume the upload
controller.Resume();

// Cancel the upload
controller.Cancel();

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

يمكنك إرفاق مستمعين بعمليات التحميل لمراقبة مستوى تقدّم عملية التحميل.

class MyListener : public firebase::storage::Listener {
 public:
  virtual void OnProgress(firebase::storage::Controller* controller) {
    // A progress event occurred
  }
};

{
  // Start uploading a file
  MyEventListener my_listener;
  storage_ref.Child("images/mountains.jpg").PutFile(local_file, my_listener);
}

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

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

الخطوات التالية

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