דרכים לחיסכון בנתונים |
|
---|---|
שים | כתיבת או החלפת נתונים בנתיב מוגדר, כמו 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.
הבקשות GET
, PUT
, POST
ו-PATCH
תומכות ב-print=silent
.
כתיבת ערכים בשרת
אפשר לכתוב ערכים של שרתים במיקום באמצעות ערך 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.