حفظ البيانات

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

PUT كتابة البيانات أو استبدالها في مسار محدّد، مثل fireblog/users/user1/<data>
PATCH تعديل بعض المفاتيح لمسار محدّد بدون استبدال كل البيانات
طريقة 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 واحدة فقط لكل طلب if-match، وليس قيمًا متعدّدة.
  • على الرغم من أنّ المعيار يقترح عرض علامات ETag مع جميع الطلبات، فإنّ "قاعدة بيانات الوقت الفعلي" لا تعرض علامات ETag إلا مع الطلبات التي تتضمّن العنوان X-Firebase-ETag. ويؤدي ذلك إلى تقليل تكاليف الفوترة للطلبات العادية.

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

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

لإنشاء مفتاح فريد يستند إلى الطابع الزمني لكل عنصر فرعي تمت إضافته إلى مرجع قاعدة بيانات Firebase، يمكننا إرسال طلب POST. بالنسبة إلى مسار 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 تحديد تنسيق ردّنا من database. ستؤدي إضافة 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 في القسم التالي.