אחזור נתונים

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

אפשר לסנן נתונים באחת משלוש דרכים: לפי מפתח צאצא, לפי מפתח או לפי value. שאילתה מתחילה באחד מהפרמטרים האלה, ולאחר מכן צריך לשלב אותה עם אחד או יותר מהפרמטרים הבאים: 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 כדי למצוא את כל הדינוזאורים שהשמות שלהם הופיעו לפני פטרודקטילוס לקסיקוגרפיה:

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="$Priorityity"

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

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

לקבלת מידע נוסף על עדיפויות, ניתן לעיין ב הפניית API.

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

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

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

  1. הגדרת הכותרת 'אישור' של הלקוח בתור 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 יהיו אובייקט עם שני מפתחות: נתיב ונתונים
הנתיב מצביע על מיקום ביחס לכתובת ה-URL של הבקשה
לכל מפתח בנתונים, הלקוח צריך להחליף את המפתח המתאים במטמון שלו בנתונים של המפתח הזה בהודעה
הודעת keep-alive הנתונים עבור האירוע הזה ריקים, לא נדרשת פעולה
cancel הנתונים של האירוע הזה הם null
האירוע הזה נשלח אם Firebase Realtime Database Security Rules גורם לכך שלא ניתן יהיה יותר לקרוא במיקום המבוקש
auth_revok הנתונים עבור האירוע הזה הם מחרוזת שמציינת שתוקף פרטי הכניסה פג
האירוע הזה יישלח כשפרמטר האימות שסופק כבר לא תקף

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

// 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, wrapper של צד שלישי מסביב ל-REST API של Firebase ו-Stream API.