حفظ البيانات

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

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

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

  • يمكنك توفير قيمة ETag واحدة فقط لكل طلب إذا تطابق ، وليس عدة.
  • بينما يقترح المعيار إرجاع ETags مع جميع الطلبات ، فإن Realtime Database تقوم فقط بإرجاع 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 للمسار الذي نرغب في حذف البيانات منه. سيؤدي ما يلي إلى حذف Alan من مسار users :

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

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

معلمات URI

تقبل واجهة برمجة تطبيقات REST معلمات 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 إلى طلبنا. ستكون الاستجابة الناتجة فارغة وسيشار إليها برمز حالة 204 No Content HTTP إذا كان الطلب ناجحًا. 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 API طويل جدًا.
  • يحتوي الطلب على قيمة خادم غير معروفة.
  • لم يتم تحديد فهرس طلب البحث في قواعد أمان قاعدة بيانات Firebase Realtime .
  • لا يدعم الطلب أحد معامِلات الاستعلام المحددة.
  • يخلط الطلب بين معلمات الاستعلام وطلب GET الضحل.
401 غير مصرح به

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

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

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

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

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