حفظ البيانات

طرق حفظ البيانات

PUT كتابة البيانات أو استبدالها في مسار محدّد، مثل fireblog/users/user1/<data>
رمز التصحيح تحديث بعض المفاتيح لمسار محدد دون استبدال جميع البيانات.
طريقة POST الإضافة إلى قائمة البيانات في قاعدة بيانات Firebase في كل مرة نرسل فيها طلب POST، يُنشئ عميل Firebase مفتاحًا فريدًا، مثل fireblog/users/<unique-id>/<data>.
حذف إزالة البيانات من مرجع قاعدة بيانات Firebase المحدّد

كتابة البيانات باستخدام PUT

عملية الكتابة الأساسية من خلال واجهة برمجة التطبيقات REST هي PUT. ولشرح عملية حفظ البيانات، سننشئ تطبيق تدوين يحتوي على المشاركات والمستخدمين. سيتم تخزين كل بيانات تطبيقنا ضمن مسار fireblog، على عنوان URL لقاعدة بيانات Firebase `https://docs-examples.firebaseio.com/fireblog`.

لنبدأ بحفظ بعض بيانات المستخدمين في قاعدة بيانات Firebase. سنخزِّن كل مستخدم من خلال اسم مستخدم فريد، كما سنخزِّن اسمه بالكامل وتاريخ ميلاده. بما أنّ كل مستخدم سيكون لديه اسم مستخدم فريد، من المنطقي استخدام PUT هنا بدلاً من POST لأنّه لدينا المفتاح ولا نحتاج إلى إنشاء مفتاح آخر.

باستخدام PUT، يمكننا كتابة سلسلة أو رقم أو قيمة منطقية أو مصفوفة أو أي كائن JSON في قاعدة بيانات Firebase. في هذه الحالة، سنُمرِّر إليه عنصرًا:

curl -X PUT -d '{
  "alanisawesome": {
    "name": "Alan Turing",
    "birthday": "June 23, 1912"
  }
}' 'https://docs-examples.firebaseio.com/fireblog/users.json'

عند حفظ عنصر JSON في قاعدة البيانات، تتم ربط سمات العنصر تلقائيًا بالمواقع الجغرافية الفرعية بطريقة مُدمجة. إذا انتقلنا إلى العقدة التي تم إنشاؤها حديثًا، ستظهر لنا القيمة "Alan Turing". يمكننا أيضًا حفظ البيانات مباشرةً في موقع جغرافي خاص بالطفل:

curl -X PUT -d '"Alan Turing"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/birthday.json'

في المثالَين أعلاه، يتم حفظ البيانات نفسها في قاعدة بيانات Firebase عند كتابة القيمة في الوقت نفسه ككائن وكتابة القيمتين بشكل منفصل في المواقع الفرعية:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing"
    }
  }
}

ستتم الإشارة إلى الطلب الناجح من خلال رمز حالة HTTP 200 OK، وستتضمّن الاستجابة البيانات التي أرسلناها إلى قاعدة البيانات. لن يؤدي المثال الأول إلا إلى بدء حدث واحد على العملاء الذين يراقبون البيانات، في حين سيؤدي المثال الثاني إلى بدء حدثَين. من المهمّ الإشارة إلى أنّه إذا كانت البيانات متوفّرة في مسار المستخدمين، ستؤدي الطريقة الأولى إلى استبدالها، ولكنّ الطريقة الثانية ستُعدّل فقط قيمة كلّ عنصر من عناصر "الطفل" المنفصلة مع إبقاء العناصر الأخرى بدون تغيير. الدالة PUT تعادل set() في حزمة JavaScript SDK.

تعديل البيانات باستخدام PATCH

باستخدام طلب PATCH، يمكننا تعديل بيانات أطفال محدّدين في موقع جغرافي معيّن بدون تبديل البيانات الحالية. لنضيف اسم Turing المعرِّف إلى بيانات المستخدم من خلال طلب PATCH:

curl -X PATCH -d '{
  "nickname": "Alan The Machine"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

سيؤدي الطلب أعلاه إلى كتابة nickname في عنصر alanisawesome بدون حذف العنصرَين الفرعيين name أو birthday. يُرجى العِلم أنّه إذا أرسلنا طلب PUT هنا بدلاً من ذلك، سيتم حذف name وbirthday لأنّهما لم يتم تضمينهما في الطلب. تظهر البيانات في قاعدة بيانات Firebase الآن على النحو التالي:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    }
  }
}

سيتم الإشارة إلى الطلب الناجح من خلال رمز حالة HTTP‏ 200 OK، وسيحتوي الردّ على البيانات المعدَّلة التي تمّ كتابتها في قاعدة البيانات.

تتيح Firebase أيضًا التحديثات عبر مسارات متعددة. يعني ذلك أنّه يمكن الآن لـ PATCH تعديل القيم في مواقع جغرافية متعدّدة في قاعدة بيانات Firebase في الوقت نفسه، وهي ميزة فعّالة تساعدك في إزالة المعالجة العادية لبياناتك. باستخدام تعديلات المسارات المتعددة، يمكننا إضافة ألقاب لكل من "آدم" و"نور" في الوقت نفسه:

curl -X PATCH -d '{
  "alanisawesome/nickname": "Alan The Machine",
  "gracehopper/nickname": "Amazing Grace"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

بعد هذا التعديل، تمت إضافة الألقاب لكل من "آدم" و"نور":

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "date_of_birth": "December 9, 1906",
      "full_name": "Grace Hopper",
      "nickname": "Amazing Grace"
    }
  }
}

يُرجى العِلم أنّ محاولة تعديل العناصر عن طريق كتابة عناصر تتضمّن المسارات المضمّنة سيؤدي إلى سلوك مختلف. لنلقِ نظرة على ما سيحدث إذا حاولنا بدلاً من ذلك تعديل معلومات "غريس" و"ألان" بهذه الطريقة:

curl -X PATCH -d '{
  "alanisawesome": {"nickname": "Alan The Machine"},
  "gracehopper": {"nickname": "Amazing Grace"}
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

يؤدي ذلك إلى سلوك مختلف، وهو استبدال عقدة /fireblog/users بأكملها:

{
  "users": {
    "alanisawesome": {
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "nickname": "Amazing Grace"
    }
  }
}

تعديل البيانات باستخدام الطلبات الشَرطية

يمكنك استخدام الطلبات المشروطة، التي تعادل REST للمعاملات، لتعديل البيانات وفقًا لحالتها الحالية. على سبيل المثال، إذا كنت تريد زيادة عدد الأصوات المؤيّدة، وتريد التأكّد من أنّه يعكس بدقة عدد الأصوات المؤيّدة المتعدّدة والمتزامنة، استخدِم طلبًا مشروطًا لكتابة القيمة الجديدة في العداد. بدلاً من إجراء عمليتَي كتابة تؤديان إلى تغيير المعداد إلى الرقم نفسه، يتعذّر إكمال أحد طلبات الكتابة ويمكنك بعد ذلك إعادة محاولة الطلب باستخدام القيمة الجديدة.
  1. لتنفيذ طلب شَرطي في موقع جغرافي، احصل على المعرّف الفريد للبيانات الحالية في ذلك الموقع الجغرافي، أو علامة ETag. إذا تغيّرت البيانات في هذا الموضع، سيتغيّر علامة ETag أيضًا. يمكنك طلب علامة ETag باستخدام أي طريقة أخرى غير PATCH. يستخدم المثال التالي طلب GET.
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    يؤدي استدعاء ETag تحديدًا في العنوان إلى عرض العلامة ETag للموقع المحدد في استجابة HTTP.
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    10 // Current value of the data at the specified location
  2. أدرِج علامة ETag التي تم عرضها في طلب PUT أو DELETE التالي لتعديل البيانات التي تتطابق على وجه التحديد مع قيمة ETag هذه. ووفقًا للمثال الذي ذكرناه، يمكنك تعديل العدّاد إلى 11 أو 1 أكبر من القيمة الأولية التي تم استرجاعها وهي 10، وإخفاق الطلب في حال لم تعُد القيمة مطابقة، استخدِم الرمز التالي:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    إذا كانت قيمة البيانات في الموقع المحدّد لا تزال 10، تتطابق علامة ETag في طلب PUT، وينجح الطلب، مع كتابة 11 في قاعدة البيانات.
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    Cache-Control: no-cache
    
    11 // New value of the data at the specified location, written by the conditional request
    إذا لم يعُد الموقع الجغرافي مطابقًا لرمز ETag، وهو ما قد يحدث إذا كتب مستخدم آخر قيمة جديدة في قاعدة البيانات، سيتعذّر إرسال الطلب بدون كتابة إلى الموقع الجغرافي. تتضمن استجابة الإرجاع القيمة الجديدة وعلامة ETag.
    HTTP/1.1 412 Precondition Failed
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    12 // New value of the data at the specified location
  3. استخدِم المعلومات الجديدة إذا قرّرت إعادة محاولة إرسال الطلب. Realtime Database لا يعيد تلقائيًا محاولة الطلبات الشَرطية التي تعذّر إكمالها. ومع ذلك، يمكنك استخدام القيمة الجديدة وعلامة ETag لإنشاء طلب مشروط جديد باستخدام المعلومات التي عرضها استجابة الخطأ.

تنفِّذ الطلبات الشَرطية المستندة إلى REST معيار HTTP if-match. ومع ذلك، فهي تختلف عن المعيار في النواحي التالية:

  • يمكنك تقديم قيمة ETag واحدة فقط لكل طلب إذا كانت المطابقة، وليس عدة طلبات.
  • على الرغم من أنّ المعيار يقترح عرض علامات ETag مع جميع الطلبات، لا تعرض قاعدة بيانات الوقت الفعلي سوى علامات ETag مع الطلبات التي تشمل عنوان X-Firebase-ETag. ويؤدي ذلك إلى تقليل تكاليف الفوترة للطلبات العادية.

قد تكون الطلبات الشَرطية أيضًا أبطأ من طلبات REST العادية.

حفظ قوائم البيانات

يمكننا إرسال طلب POST لإنشاء مفتاح فريد يستند إلى الطابع الزمني لكل عنصر ثانوي تتم إضافته إلى مرجع قاعدة بيانات Firebase. بالنسبة إلى مسار users، كان من المنطقي تحديد مفاتيح خاصة بنا لأنّ كل مستخدم لديه اسم مستخدم فريد. ولكن عندما يضيف المستخدمون مشاركات مدونة إلى تطبيقك، سنستخدم طلب POST لإنشاء مفتاح تلقائيًا لكل مشاركة مدونة:

curl -X POST -d '{
  "author": "alanisawesome",
  "title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'

يتضمّن مسار posts الآن البيانات التالية:

{
  "posts": {
    "-JSOpn9ZC54A4P4RoqVa": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

يُرجى العلم أنّه تم إنشاء المفتاح -JSOpn9ZC54A4P4RoqVa تلقائيًا لنا لأنّنا استخدمنا طلب POST. ستتم الإشارة إلى الطلب الناجح من خلال رمز حالة HTTP 200 OK، وستتضمّن الاستجابة مفتاح البيانات الجديدة التي تمت إضافتها:

{"name":"-JSOpn9ZC54A4P4RoqVa"}

إزالة البيانات

لإزالة بيانات من قاعدة البيانات، يمكننا إرسال طلب DELETE يتضمن عنوان URL للمسار الذي نريد حذف البيانات منه. سيؤدي ما يلي إلى حذف "علي" من مسار users:

curl -X DELETE \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

يُشار إلى طلب DELETE الناجح من خلال رمز حالة HTTP‏ 200 OK مع استجابة تحتوي على null بتنسيق JSON.

مَعلمات معرّف الموارد المنتظم (URI)

تقبل واجهة برمجة التطبيقات REST API مَعلمات عناوين URL التالية عند كتابة البيانات في قاعدة البيانات:

auth

تسمح مَعلمة الطلب auth بالوصول إلى البيانات المحمية باستخدام Firebase Realtime Database Security Rules، وهي متوافقة مع جميع أنواع الطلبات. ويمكن أن تكون الوسيطة إما سر تطبيق Firebase أو رمزًا مميزًا للمصادقة، وهو ما سنتناوله في قسم تفويض المستخدم. في المثال التالي، نرسل طلب POST مع مَعلمة auth، حيث يكون CREDENTIAL إما مفتاح تطبيق Firebase السري أو رمز مصادقة:

curl -X POST -d '{"Authenticated POST request"}' \
  'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'

طباعة

تتيح لنا المعلَمة print تحديد تنسيق الردّ من قاعدة البيانات. ستؤدي إضافة print=pretty إلى طلبنا إلى عرض البيانات بتنسيق يمكن لشخص عادي قراءته. يمكن استخدام print=pretty من خلال طلبات GET PUT وPOST وPATCH وDELETE.

لإيقاف الإخراج من الخادم عند كتابة البيانات، يمكننا إضافة السمة print=silent إلى طلبنا. ستكون الاستجابة الناتجة فارغة ويُشار إليها برمز حالة HTTP 204 No Content إذا كان الطلب ناجحًا. يمكن استخدام print=silent مع طلبات GET وPUT POST وPATCH.

كتابة قيم الخادم

يمكن كتابة قيم الخادم في موقع باستخدام قيمة عنصر نائب، وهو عنصر يحتوي على مفتاح".sv" واحد. قيمة هذا المفتاح هي نوع قيمة الخادم التي نريد ضبطها. على سبيل المثال، لضبط طابع زمني عند إنشاء مستخدم، يمكننا إجراء ما يلي:

curl -X PUT -d '{".sv": "timestamp"}' \
  'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'

"timestamp" هي قيمة الخادم الوحيدة المتوافقة، وهي الوقت بالملي ثانية منذ بدء حساب الفترة في نظام التشغيل UNIX.

تحسين أداء الكتابة

إذا كنا نكتب كميات كبيرة من البيانات في قاعدة البيانات، يمكننا استخدام المَعلمة print=silent لتحسين أداء الكتابة وخفض استخدام سرعة نقل البيانات. في السلوك العادي للكتابة، يستجيب الخادم ببيانات JSON التي تمّت كتابتها. عند تحديد print=silent، يغلق الخادم على الفور الاتصال بعد تلقّي البيانات، ما يقلل من استخدام معدل نقل البيانات.

في الحالات التي نُجري فيها العديد من الطلبات إلى قاعدة البيانات، يمكننا إعادة استخدام اتصال HTTPS من خلال إرسال طلب Keep-Alive في عنوان HTTP.

حالات الخطأ

ستعرض واجهة برمجة تطبيقات REST رموز الخطأ في ظل الظروف التالية:

رموز حالة HTTP
400 طلب غير صالح

أحد شروط الخطأ التالية:

  • تعذّر تحليل بيانات PUT أو POST.
  • بيانات PUT أو POST غير متوفّرة
  • يحاول الطلب PUT أو POST بيانات كبيرة جدًا.
  • تحتوي طلب بيانات واجهة برمجة التطبيقات REST API على أسماء عناصر فرعية غير صالحة كجزء من المسار.
  • مسار طلب البيانات من واجهة برمجة التطبيقات REST طويل جدًا.
  • يحتوي الطلب على قيمة خادم غير معروفة.
  • لم يتم تحديد فهرس طلب البحث في Firebase Realtime Database Security Rules.
  • لا يتيح الطلب استخدام إحدى مَعلمات طلب البحث المحدّدة.
  • يمزج الطلب مَعلمات طلب البحث مع طلب GET سطحي.
401 غير مصرّح به

أحد شروط الخطأ التالية:

  • انتهت صلاحية رمز المصادقة.
  • رمز التفويض المستخدَم في الطلب غير صالح.
  • تعذّرت المصادقة باستخدام access_token.
  • ينتهك الطلب Firebase Realtime Database Security Rules.
404 لم يتم العثور على الصفحة تعذّر العثور على قاعدة بيانات Firebase المحدّدة.
500 خطأ في الخادم الداخلي عرَض الخادم خطأ. يُرجى الاطّلاع على رسالة الخطأ للحصول على مزيد من التفاصيل.
503 الخدمة غير متاحة قاعدة بيانات Firebase في الوقت الفعلي المحدّدة غير متاحة مؤقتًا، ما يعني أنّه لم تتم محاولة إرسال الطلب.

تأمين البيانات

تتضمّن Firebase لغة أمان تتيح لنا تحديد المستخدمين الذين لديهم إذن بالقراءة والكتابة في العقد المختلفة لبياناتنا. يمكنك الاطّلاع على مزيد من المعلومات حول هذا الموضوع في Realtime Database Security Rules.

بعد أن تناولنا حفظ البيانات، يمكننا في القسم التالي معرفة كيفية استرداد البيانات من قاعدة بيانات Firebase من خلال REST API.