דרכים לחיסכון בנתונים |
|
---|---|
שים | כתיבה או החלפה של נתונים בנתיב מוגדר, כמו fireblog/users/user1/<data> |
תיקון | עדכון של חלק מהמפתחות לנתיב מוגדר בלי להחליף את כל הנתונים. |
פרסם | להוסיף לרשימת נתונים במסד הנתונים של Firebase. בכל פעם ששולחים בקשה מסוג POST , לקוח Firebase יוצר מפתח ייחודי, כמו fireblog/users/<unique-id>/<data> |
מחיקה | הסרת נתונים מהפנייה שצוינה למסד הנתונים של Firebase. |
כתיבת נתונים באמצעות PUT
פעולת הכתיבה הבסיסית דרך ה-API ל-REST היא PUT
. כדי להמחיש את שמירת הנתונים, נבנה אפליקציית ניהול בלוגים עם פוסטים ומשתמשים. כל הנתונים של האפליקציה שלנו יישמרו בנתיב fireblog, בכתובת ה-URL של מסד הנתונים של Firebase: https://docs-examples.firebaseio.com/fireblog.
נתחיל בשמירת נתוני משתמשים מסוימים במסד הנתונים של Firebase. נאחסן כל משתמש לפי שם משתמש
ייחודי, וגם נשמור את השם המלא ותאריך הלידה שלו. מאחר שלכל משתמש יהיה שם משתמש ייחודי, מומלץ להשתמש כאן ב-PUT
במקום ב-POST
, כי המפתח כבר קיים ואין צורך ליצור מפתח חדש.
באמצעות PUT
, אפשר לכתוב למסד הנתונים של Firebase מחרוזת, מספר, ערך בוליאני, מערך או כל אובייקט JSON. במקרה כזה, נעביר לו אובייקט:
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 בו-זמנית. זוהי תכונה חזקה שעוזרת לבטל את הנורמליזציה של הנתונים. באמצעות עדכונים מרובי-נתיבים, אנו יכולים להוסיף כינויים גם לאלן וגם לגרייס בו-זמנית:
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, כדי לעדכן את הנתונים בהתאם למצב הקיים שלהם. לדוגמה, אם רוצים להגדיל את מספר הלייקים ורוצים לוודא שהספירה משקפת באופן מדויק יותר מכמה לייקים בו-זמנית, אפשר להשתמש בבקשה מותנית כדי לכתוב את הערך החדש למונה. במקום שתי פעולות כתיבה שמחליפות את המונה לאותו מספר, אחת מבקשות הכתיבה נכשלת ואז אפשר לנסות שוב את הבקשה עם הערך החדש.- כדי לבצע בקשה מותנית במיקום מסוים, צריך לקבל את המזהה הייחודי של הנתונים הנוכחיים במיקום הזה, או את ה-ETag. אם הנתונים משתנים
במיקום הזה, גם ה-ETag משתנה. אפשר לבקש ETag בכל שיטה חוץ מ-
PATCH
. בדוגמה הבאה נעשה שימוש בבקשה מסוגGET
. קריאה ספציפית ל-ETag בכותרת מחזירה את ה-ETag של המיקום שצוין בתגובה ל-HTTP.curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
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
- כדי לעדכן נתונים שתואמים באופן ספציפי לערך ה-ETag הזה, צריך לכלול את ה-ETag שהוחזר בבקשה הבאה של
PUT
אוDELETE
. בהמשך לדוגמה שלנו, כדי לעדכן את המונה ל-11, או לערך גבוה ב-1 מהערך הראשוני שאוחזר (10), ולהכשיל את הבקשה אם הערך כבר לא תואם, צריך להשתמש בקוד הבא: אם הערך של הנתונים במיקום שצוין עדיין הוא 10, ה-ETag בבקשהcurl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
PUT
תואם והבקשה תצליח, והערך 11 יירשם במסד הנתונים. אם המיקום כבר לא תואם ל-ETag, מצב שעלול לקרות אם משתמש אחר כתב ערך חדש במסד הנתונים, הבקשה תיכשל בלי לכתוב למיקום. התשובה שתקבלו תכלול את הערך החדש ואת ה-ETag.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
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
- אם תחליטו לנסות שוב את הבקשה, תוכלו להשתמש במידע החדש. Realtime Database לא ינסה מחדש באופן אוטומטי בקשות מותנות שנכשלו. עם זאת, אפשר להשתמש בערך החדש וב-ETag כדי ליצור בקשה מותנית חדשה עם המידע שהוחזר בתגובה לכישלון.
בקשות מותנות מבוססות-REST מיישמות את התקן if-match של HTTP. עם זאת, הם שונים מהסטנדרט בדרכים הבאות:
- אפשר לציין רק ערך ETag אחד לכל בקשה של if-match, ולא כמה בקשות.
- הסטנדרט מציע להחזיר את ה-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
ה-API ל-REST מקבל את פרמטרי ה-URI הבאים כשכותבים נתונים למסד הנתונים:
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
לבקשה שלנו. אם הבקשה תאושר, התגובה שתתקבל תהיה ריקה ותכלול את קוד הסטטוס 204 No Content
של HTTP.
השדה print=silent
נתמך על ידי הבקשות GET
, PUT
, POST
ו-PATCH
.
כתיבת ערכים בשרת
אפשר לכתוב את ערכי השרת במיקום באמצעות ערך placeholder, שהוא אובייקט עם מפתח ".sv"
יחיד. הערך של המפתח הזה הוא סוג ערך השרת שאנחנו רוצים להגדיר.
לדוגמה, כדי להגדיר חותמת זמן כשיוצרים משתמש, אפשר לבצע את הפעולות הבאות:
curl -X PUT -d '{".sv": "timestamp"}' \ 'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'
"timestamp"
הוא הערך היחיד של השרת שנתמך, והוא מייצג את הזמן מאז תחילת זמן יוניקס (UNIX epoch) במיליוניות השנייה.
שיפור ביצועי כתיבה
אם אנחנו כותבים כמויות גדולות של נתונים למסד הנתונים, אפשר להשתמש בפרמטר print=silent
כדי לשפר את ביצועי הכתיבה ולהפחית את השימוש ברוחב הפס. בהתנהגות הכתיבה הרגילה, השרת משיב עם נתוני ה-JSON שנכתבו.
כשמציינים את הערך print=silent
, השרת סוגר את החיבור באופן מיידי אחרי קבלת הנתונים, וכך מפחית את השימוש ברוחב הפס.
במקרים שבהם אנחנו שולחים בקשות רבות למסד הנתונים, אפשר להשתמש שוב בחיבור HTTPS על ידי שליחת בקשת Keep-Alive
בכותרת ה-HTTP.
תנאי שגיאה
ה-API ל-REST יחזיר קודי שגיאה בנסיבות הבאות:
קודי מצב HTTP | |
---|---|
400 בקשה לא תקינה |
אחד מתנאי השגיאה הבאים:
|
401 Unauthorized |
אחד מתנאי השגיאה הבאים:
|
404 לא נמצא | מסד הנתונים של Firebase שצוין לא נמצא. |
500 שגיאת שרת פנימית | השרת החזיר שגיאה. פרטים נוספים מופיעים בהודעת השגיאה. |
503 שירות לא זמין | מסד הנתונים בזמן אמת ב-Firebase שצוין לא זמין באופן זמני, כלומר לא בוצעה ניסיון שליחת בקשה. |
אבטחת נתונים
ב-Firebase יש שפת אבטחה שמאפשרת לנו להגדיר לאילו משתמשים יש גישת קריאה וכתיבה בצמתים שונים של הנתונים שלנו. מידע נוסף זמין במאמר Realtime Database Security Rules.
אחרי שסיפרנו איך שומרים נתונים, נלמד בקטע הבא איך לאחזר את הנתונים שלנו ממסד הנתונים של Firebase דרך ה-API ל-REST.