אחזור נתונים

קריאת נתונים באמצעות GET

אנחנו יכולים לקרוא נתונים ממסד הנתונים של Firebase על ידי שליחת בקשת GET לנקודת הקצה של כתובת ה-URL שלו. נמשיך עם דוגמה לבלוג שלנו מהקטע הקודם ונקראים את כל הנתונים מהפוסטים בבלוג:

curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=pretty'

בקשה שמבוצעת בהצלחה תצוין באמצעות קוד סטטוס HTTP 200 OK, והתשובה תכיל את הנתונים שאנחנו מאחזרים.

הוספת פרמטרים של URI

כשקוראים נתונים ממסד הנתונים של Firebase, ה-API ל-REST מקבל כמה פרמטרים של שאילתה. בהמשך מפורטים הפרמטרים הנפוצים ביותר. רשימה מלאה מופיעה בחומר העזר בנושא API ל-REST.

אימות

פרמטר הבקשה auth מאפשר גישה לנתונים שמוגנים על ידי Firebase Realtime Database Security Rules, וכל סוגי הבקשות תומכים בו. הארגומנט יכול להיות הסוד של אפליקציית Firebase או אסימון אימות, כפי שמתואר במאמר משתמשים בפרויקטים של Firebase. בדוגמה הבאה נשלח בקשת GET עם הפרמטר auth, שבו CREDENTIAL הוא הסוד של אפליקציית Firebase שלכם או אסימון אימות:

curl 'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'

הדפס

ציון הערך print=pretty מחזיר את הנתונים בפורמט קריא לבני אדם.

curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=pretty'

ציון הערך print=silent יחזיר 204 No Content בסיום הפעולה.

curl 'https://docs-examples.firebaseio.com/fireblog/posts.json?print=silent'

קריאה חוזרת (callback)

כדי לשלוח קריאות REST מדפדפן אינטרנט בכמה דומיינים, אפשר להשתמש ב-JSONP כדי לכלול את התשובה בפונקציית קריאה חוזרת של JavaScript. מוסיפים את callback= כדי לאפשר ל-API ל-REST לעטוף את הנתונים המוחזרים בפונקציית הקריאה החוזרת שציינתם. לדוגמה:

<script>
  function gotData(data) {
    console.log(data);
  }
</script>
<script src="https://docs-examples.firebaseio.com/fireblog/posts.json?callback=gotData">

רדוד

זוהי תכונה מתקדמת שנועדה לעזור לך לעבוד עם מערכי נתונים גדולים בלי שיהיה צורך להוריד הכול. כדי להשתמש בו, מוסיפים את shallow=true כפרמטר. הפעולה הזו תגביל את העומק של הנתונים שמוחזרים. אם הנתונים במיקום הם פרימטיב של JSON (מחרוזת, מספר או ערך בוליאני), הערך שלהם יוחזר. אם תמונת המצב של הנתונים במיקום היא אובייקט JSON, הערכים של כל מפתח יקוצרו ל-true. לדוגמה, באמצעות הנתונים הבאים:

{
  "message": {
    "user": {
      "name": "Chris"
    },
    "body": "Hello!"
  }
}

// A request to /message.json?shallow=true
// would return the following:
{
  "user": true,
  "body": true
}

// A request to /message/body.json?shallow=true
// would simply return:
"Hello!"

אפשר לנסות אותו עם הבקשה הבאה של curl:

curl 'https://docs-examples.firebaseio.com/rest/retrieving-data.json?shallow=true&print=pretty'

זמן קצוב לתפוגה

אפשר להשתמש באפשרות הזו כדי להגביל את משך הזמן של הקריאה בצד השרת. אם בקשת קריאה לא מסתיימת במסגרת הזמן שהוקצב, היא תסתיים בשגיאת HTTP 400. האפשרות הזו שימושית במיוחד כשצפויה העברה של כמות קטנה של נתונים, ולא רוצים להמתין זמן רב מדי כדי לאחזר עץ משנה שעשוי להיות גדול מאוד. זמן הקריאה בפועל עשוי להשתנות בהתאם לגודל הנתונים ולאחסון במטמון.

מציינים את timeouts בפורמט הבא: 3ms,‏ 3s או 3min, עם מספר ויחידת מידה. אם לא מציינים את הפרמטר הזה, המערכת תחיל את הערך המקסימלי timeout של 15min. אם הערך של timeout הוא לא חיובי, או שהוא חורג מהמקסימום, הבקשה תידחה ותוצג שגיאת HTTP 400. בדוגמה הבאה, הבקשה GET כוללת timeout של 10 שניות.

curl 'https://docs-examples.firebaseio.com/rest/retrieving-data.json?timeout=10s'

סינון נתונים

אנחנו יכולים ליצור שאילתות כדי לסנן נתונים על סמך גורמים שונים. בשלב הראשון, מציינים את האופן שבו רוצים לסנן את הנתונים באמצעות הפרמטר orderBy. לאחר מכן, משלבים את orderBy עם כל אחד מחמשת הפרמטרים האחרים: limitToFirst, limitToLast, startAt, endAt ו-equalTo.

אנחנו ב-Firebase חושבים שדינוזאורים הם מגניבים, ולכן נשתמש בקטע מקצר ממסד נתונים לדוגמה של עובדות על דינוזאורים כדי להדגים איך אפשר לסנן נתונים:

{
  "lambeosaurus": {
    "height": 2.1,
    "length": 12.5,
    "weight": 5000
  },
  "stegosaurus": {
    "height": 4,
    "length": 9,
    "weight": 2500
  }
}

אנחנו יכולים לסנן נתונים באחת משלוש דרכים: לפי מפתח צאצא, לפי מפתח או לפי ערך. שאילתה מתחילה באחד מהפרמטרים האלה, ולאחר מכן צריך לשלב אותה עם אחד או יותר מהפרמטרים הבאים: startAt, endAt, limitToFirst, limitToLast או equalTo.

סינון לפי מפתח צאצא ספציפי

אפשר לסנן צמתים לפי מפתח צאצא משותף על ידי העברת המפתח הזה לפרמטר orderBy. לדוגמה, כדי לאחזר את כל הדינוזאורים שגובהם גדול מ-3, אפשר לבצע את הפעולות הבאות:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&startAt=3&print=pretty'

כל צומת שאין לו את מפתח הצאצא שאנחנו מסננים לפיו ימוין עם הערך null. פרטים על סדר הנתונים מופיעים במאמר סדר הנתונים.

ב-Firebase יש גם תמיכה בשאילתות שממוינות לפי צאצאים שמוטמעים לעומק, ולא רק לפי צאצאים ברמה אחת למטה. האפשרות הזו שימושית אם יש לכם נתונים שמקובצים לעומק, כמו זה:

{
  "lambeosaurus": {
    "dimensions": {
      "height" : 2.1,
      "length" : 12.5,
      "weight": 5000
    }
  },
  "stegosaurus": {
    "dimensions": {
      "height" : 4,
      "length" : 9,
      "weight" : 2500
    }
  }
}

כדי להריץ עכשיו שאילתה על הגובה, נשתמש בנתיב המלא של האובייקט ולא במפתח יחיד:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="dimensions/height"&startAt=3&print=pretty'

אפשר לסנן שאילתות לפי מפתח אחד בלבד בכל פעם. שימוש בפרמטר orderBy כמה פעמים באותה בקשה יגרום לשגיאה.

סינון לפי מפתח

אפשר גם לסנן צמתים לפי המפתחות שלהם באמצעות הפרמטר orderBy="$key". בדוגמה הבאה מתבצעת אחזור של כל הדינוזאורים שהשם שלהם מתחיל באות a ועד m:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&startAt="a"&endAt="m"&print=pretty'

סינון לפי ערכים

אנחנו יכולים לסנן צמתים לפי הערך של מפתחות הצאצא שלהם באמצעות הפרמטר orderBy="$value". נניח שהדינוזאורים מקיימים תחרות ספורט דינוזאורים, ואנחנו עוקבים אחרי התוצאות שלהם בפורמט הבא:

{
  "scores": {
    "bruhathkayosaurus": 55,
    "lambeosaurus": 21,
    "linhenykus": 80,
    "pterodactyl": 93,
    "stegosaurus": 5,
    "triceratops": 22
  }
}

כדי לאחזר את כל הדינוזאורים עם ציון גבוה מ-50, אפשר לשלוח את הבקשה הבאה:

curl 'https://dinosaur-facts.firebaseio.com/scores.json?orderBy="$value"&startAt=50&print=pretty'

במאמר אופן הסדר של הנתונים מוסבר איך ממוינים ערכים של null, בוליאני, מחרוזות ואובייקטים כשמשתמשים ב-orderBy="$value".

סינון מורכב

אנחנו יכולים לשלב כמה פרמטרים כדי ליצור שאילתות מורכבות יותר.

הגבלת שאילתות

הפרמטרים limitToFirst ו-limitToLast משמשים להגדרת מספר הילדים המקסימלי שעבורם יקבלו נתונים. אם נגדיר מגבלה של 100, נקבל רק עד 100 ילדים תואמים. אם במסד הנתונים שלנו יש פחות מ-100 הודעות, נקבל את כל הילדים. עם זאת, אם יש יותר מ-100 הודעות, נקבל נתונים רק לגבי 100 מההודעות האלה. אם אנחנו משתמשים ב-limitToFirst וב-100 ההודעות האחרונות, אם אנחנו משתמשים ב-limitToLast, אלה יהיו 100 ההודעות הראשונות שמסודרות.

בעזרת מסד הנתונים של העובדות על הדינוזאורים ו-orderBy, אנחנו יכולים למצוא את שני הדינוזאורים הכבדים ביותר:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="weight"&limitToLast=2&print=pretty'

באופן דומה, אפשר למצוא את שני הדינוזאורים הקצרים ביותר באמצעות limitToFirst:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&limitToFirst=2&print=pretty'

אנחנו יכולים גם לבצע שאילתות עם הגבלות בעזרת orderBy="$value". אם רוצים ליצור לוח מנהיגות עם שלושת המתחרים המובילים עם הציון הגבוה ביותר במשחקי הדינוזאורים, אפשר לבצע את הפעולות הבאות:

curl 'https://dinosaur-facts.firebaseio.com/scores.json?orderBy="$value"&limitToLast=3&print=pretty'

שאילתות לגבי טווח

השימוש ב-startAt, ב-endAt וב-equalTo מאפשר לנו לבחור נקודות התחלה וסיום שרירותיות לשאילתות שלנו. לדוגמה, אם נרצה למצוא את כל הדינוזאורים שגובהם לפחות שלושה מטרים, נוכל לשלב את orderBy ו-startAt:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="height"&startAt=3&print=pretty'

אפשר להשתמש ב-endAt כדי למצוא את כל הדינוזאורים ששמותיהם מופיעים לפני Pterodactyl מבחינה לקסיקוגרפית:

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&endAt="pterodactyl"&print=pretty'

אפשר לשלב את startAt ו-endAt כדי להגביל את שני הקצוות של השאילתה. בדוגמה הבאה מוצאים את כל הדינוזאורים ששמם מתחיל באות "b":

curl 'https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy="$key"&startAt="b"&endAt="b\uf8ff"&print=pretty'

שאילתות טווח שימושיות גם כשצריך לפצל את הנתונים לדפים.

סיכום של כל המידע

אנחנו יכולים לשלב את כל הטכניקות האלה כדי ליצור שאילתות מורכבות. לדוגמה, אולי תרצו למצוא את השם של כל הדינוזאורים שגובהם נמוך מגובה הדינוזאור האהוב עלינו, הסטגוזאורוס, או שווה לו:

MY_FAV_DINO_HEIGHT=`curl "https://dinosaur-facts.firebaseio.com/dinosaurs/stegosaurus/height.json"`
curl "https://dinosaur-facts.firebaseio.com/dinosaurs.json?orderBy=\"height\"&endAt=${MY_FAV_DINO_HEIGHT}&print=pretty"

סדר הנתונים

בקטע הזה מוסבר איך הנתונים מסודרים כשמשתמשים בכל אחד משלושת הפרמטרים לסינון.

הזמנה לפי

כשמשתמשים ב-orderBy עם שם של מפתח צאצא, הנתונים שמכילים את מפתח הצאצא שצוין יסודרו באופן הבא:

  1. ילדים עם ערך null למפתח הצאצא שצוין מופיעים ראשונים.
  2. לאחר מכן מופיעים צאצאים עם הערך false למפתח הצאצא שצוין. אם יש כמה צאצאים עם הערך false, הם ממוינים לפי אלפבית לפי מפתח.
  3. לאחר מכן מופיעים צאצאים עם הערך true למפתח הצאצא שצוין. אם יש כמה צאצאים עם הערך true, הם ממוינים לפי מפתח אלפביתי.
  4. לאחר מכן מופיעים צאצאים עם ערך מספרי, שממוינים בסדר עולה. אם ליותר מצאצא אחד יש את אותו ערך מספרי בצומת הצאצא שצוין, הם ממוינים לפי מפתח.
  5. מחרוזות מופיעות אחרי מספרים וממוינות לפי סדר אלפביתי עולה. אם לכמה צאצאים יש אותו ערך בצומת הצאצא שצוין, הם ממוינים לפי מפתח אלפביתי.
  6. האובייקטים מופיעים בסוף וממוינים לפי מפתח מילוני בסדר עולה.
התוצאות המסוננות מוחזרות ללא סדר. אם סדר הנתונים חשוב, אתם צריכים למיין את התוצאות באפליקציה אחרי שהן מוחזרות מ-Firebase.

orderBy="$key"

כשמשתמשים בפרמטר orderBy="$key" כדי למיין את הנתונים, הנתונים יחזרו בסדר עולה לפי מפתח, באופן הבא. חשוב לזכור שמפתחות יכולים להיות רק מחרוזות.

  1. צאצאים עם מפתח שאפשר לנתח כמספר שלם של 32 ביט מופיעים קודם, וממוינים בסדר עולה.
  2. לאחר מכן מופיעים צאצאים עם ערך מחרוזת כמפתח, שממוינים לפי סדר אלפביתי עולה.

orderBy="$value"

כשמשתמשים בפרמטר orderBy="$value" כדי למיין את הנתונים, הצאצאים ימוינו לפי הערך שלהם. קריטריוני הסדר זהים לנתונים שמסודרים לפי מפתח צאצא, אבל משתמשים בערך של הצומת ולא בערך של מפתח צאצא שצוין.

orderBy="$priority"

כשמשתמשים בפרמטר orderBy="$priority" כדי למיין את הנתונים, הסדר של הצאצאים נקבע לפי העדיפות והמפתח שלהם באופן הבא. חשוב לזכור שערכים של תעדוף יכולים להיות רק מספרים או מחרוזות.

  1. ילדים ללא עדיפות (ברירת המחדל) מופיעים קודם.
  2. לאחר מכן מופיעים ילדים עם מספר כעדיפות. הם ממוינים לפי מספר לפי סדר העדיפות, מקטן לגדול.
  3. צאצאים שהעדיפות שלהם היא מחרוזת מופיעים אחרונים. הם ממוינים לפי עדיפות לפי סדר אלפביתי.
  4. כששני צאצאים יש להם אותה עדיפות (כולל ללא עדיפות), הם ממוינים לפי מפתח. המפתחות המספריים מופיעים ראשונים (ממוינים לפי סדר מספרי), ולאחר מכן המפתחות הנותרים (ממוינים לפי לקסיקוגרפיה).

למידע נוסף על עדיפויות, ראו הפניית API.

סטרימינג מה-API ל-REST

נקודות קצה ב-REST ב-Firebase תומכות בפרוטוקול EventSource / Server-Sent events, כדי לאפשר בקלות לשדר שינויים למיקום אחד במסד הנתונים של Firebase.

כדי להתחיל בסטרימינג, נצטרך לבצע את הפעולות הבאות:

  1. מגדירים את הכותרת Accept של הלקוח ל-text/event-stream
  2. כבדו הפניות אוטומטיות של HTTP, במיוחד קוד מצב HTTP 307
  3. צריך לכלול את פרמטר השאילתה auth אם המיקום של מסד הנתונים ב-Firebase מחייב הרשאת קריאה

בתמורה, השרת ישלח אירועים עם שם כשהמצב של הנתונים בכתובת ה-URL המבוקשת ישתנה. המבנה של ההודעות האלה תואם לפרוטוקול EventSource:

event: event name
data: JSON encoded data payload

השרת עשוי לשלוח את האירועים הבאים:

put הנתונים בקידוד JSON יהיו אובייקט עם שני מפתחות: נתיב ונתונים
הנתיב מפנה למיקום ביחס לכתובת ה-URL של הבקשה
הלקוח צריך להחליף את כל הנתונים שבמיקום הזה שבמטמון שלו בנתונים שניתנו בהודעה
patch הנתונים בקידוד JSON יהיו אובייקט עם שני מפתחות: path ו-data
הנתיב מפנה למיקום ביחס לכתובת ה-URL של הבקשה
לכל מפתח בנתונים, הלקוח צריך להחליף את המפתח התואם במטמון שלו בנתונים של המפתח הזה בהודעה
הודעת keep-alive הנתונים של האירוע הזה הם null, לא נדרשת פעולה
cancel הנתונים עבור האירוע הזה הם null
האירוע הזה יישלח אם הפרמטר Firebase Realtime Database Security Rules לא מאפשר יותר קריאה במיקום המבוקש
auth_revoked הנתונים של האירוע הזה הם מחרוזת שמציינת שפג התוקף של פרטי הכניסה
האירוע הזה יישלח כשפרמטר האימות שסופק כבר לא תקף

בהמשך מוצגת דוגמה לקבוצת אירועים שהשרת עשוי לשלוח:

// Set your entire cache to {"a": 1, "b": 2}
event: put
data: {"path": "/", "data": {"a": 1, "b": 2}}


// Put the new data in your cache under the key 'c', so that the complete cache now looks like:
// {"a": 1, "b": 2, "c": {"foo": true, "bar": false}}
event: put
data: {"path": "/c", "data": {"foo": true, "bar": false}}


// For each key in the data, update (or add) the corresponding key in your cache at path /c,
// for a final cache of: {"a": 1, "b": 2, "c": {"foo": 3, "bar": false, "baz": 4}}
event: patch
data: {"path": "/c", "data": {"foo": 3, "baz": 4}}

אם אתם משתמשים ב-Go, כדאי לבדוק את Firego, חבילה של צד שלישי שמקיפה את ממשקי ה-API ל-REST ולסטרימינג של Firebase.