אחזור נתונים

קריאת נתונים באמצעות 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

הפרמטר 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 כדי לעטוף את התגובה בפונקציית קריאה חוזרת (callback) של 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 מההודעות האלה. אלה יהיו 100 ההודעות הראשונות לפי הסדר אם משתמשים ב-limitToFirst, או 100 ההודעות האחרונות לפי הסדר אם משתמשים ב-limitToLast.

בעזרת מסד הנתונים של עובדות על דינוזאורים ו-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

כשמשתמשים ב-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

נקודות הקצה של Firebase REST תומכות בפרוטוקול 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 של Firebase REST ו-Streaming.