حفظ البيانات

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

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

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

عملية الكتابة الأساسية من خلال REST API هي 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 ، يمكننا تحديث أطفال محددين في موقع ما دون الكتابة فوق البيانات الموجودة. دعونا نضيف لقب تورينج إلى بيانات المستخدم الخاصة به من خلال طلب 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 الخاصة بك في نفس الوقت، وهي ميزة قوية تسمح لك بمساعدتك على إلغاء تسوية بياناتك . باستخدام التحديثات متعددة المسارات، يمكننا إضافة ألقاب لكل من Alan وGrace في نفس الوقت:

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

بعد هذا التحديث، تمت إضافة ألقاب كل من Alan وGrace:

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

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

  • يمكنك توفير قيمة ETag واحدة فقط لكل طلب مطابقة، وليس متعددة.
  • بينما يقترح المعيار إرجاع علامات ETags مع جميع الطلبات، فإن قاعدة بيانات Realtime لا تُرجع سوى علامات ETags مع الطلبات التي تتضمن رأس 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 مع استجابة تحتوي على JSON null .

معلمات URI

تقبل REST API معلمات URI التالية عند كتابة البيانات إلى قاعدة البيانات:

مصادقة

تسمح معلمة طلب auth بالوصول إلى البيانات المحمية بواسطة قواعد أمان قاعدة بيانات Firebase Realtime ، وهي مدعومة من قبل جميع أنواع الطلبات. يمكن أن تكون الوسيطة إما سر تطبيق 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 API رموز الخطأ في ظل هذه الظروف:

رموز حالة HTTP
400 طلب سىء

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

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

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

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

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

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

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