حفظ البيانات

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

وضع كتابة البيانات أو استبدالها في مسار محدّد، مثل fireblog/users/user1/<data>
رمز التصحيح تحديث بعض المفاتيح لمسار محدد دون استبدال جميع البيانات.
مشاركة يمكنك الإضافة إلى قائمة بيانات في قاعدة بيانات 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() في حزمة تطوير البرامج (SDK) الخاصة بـ JavaScript.

تحديث البيانات باستخدام التصحيح

باستخدام طلب PATCH، يمكننا تعديل عناصر فرعية محددة في موقع جغرافي معيّن بدون استبدال البيانات الحالية. يمكننا إضافة لقب "تورينج" إلى بيانات المستخدم الخاصة به من خلال طلب 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"
    }
  }
}

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

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. استخدِم المعلومات الجديدة إذا قرّرت إعادة محاولة تقديم الطلب. لا تعيد قاعدة بيانات "الوقت الفعلي" تلقائيًا محاولة تنفيذ الطلبات الشرطية التي تعذّر تنفيذها. ومع ذلك، يمكنك استخدام القيمة الجديدة وعلامة ETag لإنشاء طلب شَرطي جديد باستخدام المعلومات التي تعرضها الاستجابة للإخفاق.

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

  • يمكنك تقديم قيمة 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 مع استجابة تحتوي على JSON null.

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

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

المصادقة

تسمح معلَمة طلب auth بالوصول إلى البيانات المحمية من خلال قواعد أمان قاعدة بيانات Firebase في الوقت الفعلي، وهي متوافقة مع جميع أنواع الطلبات. ويمكن أن تكون الوسيطة إما سر تطبيق 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 على أسماء فرعية غير صالحة كجزء من المسار.
  • مسار طلب واجهة برمجة التطبيقات REST طويل جدًا.
  • يحتوي الطلب على قيمة خادم غير معروفة.
  • لم يتم تحديد فهرس طلب البحث في قواعد أمان قاعدة بيانات Firebase في الوقت الفعلي.
  • لا يتيح الطلب استخدام إحدى معلَمات طلب البحث المحدّدة.
  • يمزج الطلب بين معلَمات طلب البحث وطلب GET سطحي.
401 غير مصرَّح به

أحد حالات الخطأ التالية:

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

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

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

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