Catch up on everthing we announced at this year's Firebase Summit. Learn more

קרא וכתוב נתונים באינטרנט

(אופציונלי) אב טיפוס ובדיקה עם חבילת אמולטור מקומית של Firebase

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

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

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

  1. הוספת שורה של קוד לתצורת הבדיקה של האפליקציה שלך כדי להתחבר לאמולטור.
  2. מן השורש של ספריית הפרויקט המקומית, פועל firebase emulators:start .
  3. ביצוע שיחות מקוד האב -טיפוס של האפליקציה שלך באמצעות SDK של פלטפורמת מסד נתונים בזמן אמת כרגיל, או באמצעות ממשק ה- REST API של מסד הנתונים בזמן אמת.

מפורטת בהדרכה המעורבת מסד זמן אמת ותפקידי ענן נגישה. כמו כן כדאי להעיף מבט לעבר הקדמת Suite Emulator המקומית .

קבל הפניה למסד נתונים

כדי לקרוא או לכתוב נתונים מבסיס הנתונים, אתה צריך מופע של firebase.database.Reference :

גרסת אינטרנט 9

import { getDatabase } from "firebase/database";

const database = getDatabase();

גרסת אינטרנט 8

var database = firebase.database();

כתוב נתונים

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

נתוני Firebase מאוחזר על ידי צירוף של מאזין אסינכרוני על firebase.database.Reference . המאזין מופעל פעם אחת למצב הראשוני של הנתונים ושוב בכל פעם שהנתונים משתנים.

פעולות כתיבה בסיסיות

עבור פעולות כתיבה בסיסיות, אתה יכול להשתמש set() כדי לשמור את נתון הפניה שצוינה, החלפה כול נתון קיימים על השביל. לדוגמא יישום בלוגים חברתי עשוי להוסיף משתמש עם set() כדלקמן:

גרסת אינטרנט 9

import { getDatabase, ref, set } from "firebase/database";

function writeUserData(userId, name, email, imageUrl) {
  const db = getDatabase();
  set(ref(db, 'users/' + userId), {
    username: name,
    email: email,
    profile_picture : imageUrl
  });
}

גרסת אינטרנט 8

function writeUserData(userId, name, email, imageUrl) {
  firebase.database().ref('users/' + userId).set({
    username: name,
    email: email,
    profile_picture : imageUrl
  });
}

באמצעות set() דורסת הנתונים במיקום שצוין, לרבות כל הצמתים הילד.

קרא נתונים

האזן לאירועים בעלי ערך

כדי לקרוא נתונים על נתיב ולהקשיב לשינויים, השתמש on() או once() שיטות של firebase.database.Reference להתבונן באירועים.

מִקרֶה שימוש אופייני
value קרא והקשב לשינויים בתוכן הנתיב כולו.

אתה יכול להשתמש value האירוע לקרוא תמונת מצב סטטי של התכנים על נתיב נתון, כפי שהיה קיים בעת האירוע. שיטה זו מופעלת פעם אחת כשהמאזין מצורף ושוב בכל פעם שהנתונים, כולל ילדים, משתנים. החזרה לאירוע מועברת בתצלום המכיל את כל הנתונים במיקום זה, כולל נתוני ילדים. אם אין נתונים, תמונת המצב תחזור false כאשר אתה קורא exists() ו null כאשר אתה קורא val() על זה.

הדוגמה הבאה מדגימה יישום בלוגים חברתיים המאחזר את מספר הכוכבים של פוסט ממסד הנתונים:

גרסת אינטרנט 9

import { getDatabase, ref, onValue} from "firebase/database";

const db = getDatabase();
const starCountRef = ref(db, 'posts/' + postId + '/starCount');
onValue(starCountRef, (snapshot) => {
  const data = snapshot.val();
  updateStarCount(postElement, data);
});

גרסת אינטרנט 8

var starCountRef = firebase.database().ref('posts/' + postId + '/starCount');
starCountRef.on('value', (snapshot) => {
  const data = snapshot.val();
  updateStarCount(postElement, data);
});

המאזין מקבל snapshot המכיל את הנתונים במיקום שצוין באתר בעת האירוע. ניתן לאחזר את הנתונים snapshot עם val() שיטה.

קרא נתונים פעם אחת

קרא נתונים פעם עם get ()

ה- SDK נועד לנהל אינטראקציות עם שרתי מסדי נתונים בין אם האפליקציה שלך מקוונת או לא מקוונת.

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

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

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

גרסת אינטרנט 9

import { getDatabase, ref, child, get } from "firebase/database";

const dbRef = ref(getDatabase());
get(child(dbRef, `users/${userId}`)).then((snapshot) => {
  if (snapshot.exists()) {
    console.log(snapshot.val());
  } else {
    console.log("No data available");
  }
}).catch((error) => {
  console.error(error);
});

גרסת אינטרנט 8

const dbRef = firebase.database().ref();
dbRef.child("users").child(userId).get().then((snapshot) => {
  if (snapshot.exists()) {
    console.log(snapshot.val());
  } else {
    console.log("No data available");
  }
}).catch((error) => {
  console.error(error);
});

קרא נתונים פעם אחת עם משקיף

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

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

גרסת אינטרנט 9

import { getDatabase, ref, onValue } from "firebase/database";
import { getAuth } from "firebase/auth";

const db = getDatabase();
const auth = getAuth();

const userId = auth.currentUser.uid;
return onValue(ref(db, '/users/' + userId), (snapshot) => {
  const username = (snapshot.val() && snapshot.val().username) || 'Anonymous';
  // ...
}, {
  onlyOnce: true
});

גרסת אינטרנט 8

var userId = firebase.auth().currentUser.uid;
return firebase.database().ref('/users/' + userId).once('value').then((snapshot) => {
  var username = (snapshot.val() && snapshot.val().username) || 'Anonymous';
  // ...
});

עדכון או מחיקה של נתונים

עדכן שדות ספציפיים

כדי לכתוב בו זמנית לילדים ספציפיים של צומת מבלי להחליף צומת ילד אחרים, להשתמש update() השיטה.

בעת התקשרות update() , אתה יכול לעדכן ערכי ילד ברמה נמוכה יותר על ידי ציון נתיב עבור המפתח. אם הנתונים מאוחסנים במקומות מרובים סולם טוב יותר, אתה יכול לעדכן את כל המופעים של נתונים באמצעות מאוורר-אאוט נתונים .

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

גרסת אינטרנט 9

function writeNewPost(uid, username, picture, title, body) {
  const db = getDatabase();

  // A post entry.
  const postData = {
    author: username,
    uid: uid,
    body: body,
    title: title,
    starCount: 0,
    authorPic: picture
  };

  // Get a key for a new Post.
  const newPostKey = push(child(ref(db), 'posts')).key;

  // Write the new post's data simultaneously in the posts list and the user's post list.
  const updates = {};
  updates['/posts/' + newPostKey] = postData;
  updates['/user-posts/' + uid + '/' + newPostKey] = postData;

  return update(ref(db), updates);
}

גרסת אינטרנט 8

function writeNewPost(uid, username, picture, title, body) {
  // A post entry.
  var postData = {
    author: username,
    uid: uid,
    body: body,
    title: title,
    starCount: 0,
    authorPic: picture
  };

  // Get a key for a new Post.
  var newPostKey = firebase.database().ref().child('posts').push().key;

  // Write the new post's data simultaneously in the posts list and the user's post list.
  var updates = {};
  updates['/posts/' + newPostKey] = postData;
  updates['/user-posts/' + uid + '/' + newPostKey] = postData;

  return firebase.database().ref().update(updates);
}

שימושים דוגמה זו push() כדי ליצור פוסט ב הצומת המכיל הודעות לכל המשתמשים בדומיין /posts/$postid ובמקביל לאחזר את המפתח. המפתח לאחר מכן ניתן להשתמש כדי ליצור ערך שני הודעות של המשתמש ב /user-posts/$userid/$postid .

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

הוסף שיחה חוזרת להשלמה

אם אתה רוצה לדעת מתי הנתונים שלך בוצעו, תוכל להוסיף התקשרות חזרה להשלמה. שניהם set() ו update() לקחת התקשרות השלמה אופציונלית נקראת כאשר הכתיבה כבר שבוצעה בבסיס נתון. אם השיחה לא צלחה, החזרה מועברת אובייקט שגיאה המציין מדוע התרחשה הכשל.

גרסת אינטרנט 9

import { getDatabase, ref, set } from "firebase/database";

const db = getDatabase();
set(ref(db, 'users/' + userId), {
  username: name,
  email: email,
  profile_picture : imageUrl
})
.then(() => {
  // Data saved successfully!
})
.catch((error) => {
  // The write failed...
});

גרסת אינטרנט 8

firebase.database().ref('users/' + userId).set({
  username: name,
  email: email,
  profile_picture : imageUrl
}, (error) => {
  if (error) {
    // The write failed...
  } else {
    // Data saved successfully!
  }
});

מחק נתונים

הדרך הפשוטה ביותר נתונים המחיקה היא להתקשר remove() על הפניה למיקום של הנתונים.

אתה גם יכול למחוק ידי ציון null כערך לעוד פעולת הכתיבה כגון set() או update() . אתה יכול להשתמש בטכניקה זו עם update() כדי למחוק ילדים מרובים בשיחת API יחידה.

קבלת Promise

כדי לדעת מתי הנתונים שלך מחויבת לשרת מסד Firebase זמן אמת, אתה יכול להשתמש Promise . שניהם set() ו update() יכולה להחזיר Promise אתה יכול להשתמש בו כדי לדעת מתי כתיבה מחויבת למסד הנתונים.

נתק מאזינים

התקשרויות חוזרות יוסרו על ידי קריאה off() שיטה על הפנייה למאגר הנתונים Firebase שלך.

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

קורא off() על מאזין ההורה אינו מסיר אוטומטית המאזינים רשום על בלוטות הילד שלה; off() חייב גם להיקרא על כול מאזיני ילד להסיר את ההתקשרות.

שמור נתונים כעסקאות

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

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

גרסת אינטרנט 9

import { getDatabase, ref, runTransaction } from "firebase/database";

function toggleStar(uid) {
  const db = getDatabase();
  const postRef = ref(db, '/posts/foo-bar-123');

  runTransaction(postRef, (post) => {
    if (post) {
      if (post.stars && post.stars[uid]) {
        post.starCount--;
        post.stars[uid] = null;
      } else {
        post.starCount++;
        if (!post.stars) {
          post.stars = {};
        }
        post.stars[uid] = true;
      }
    }
    return post;
  });
}

גרסת אינטרנט 8

function toggleStar(postRef, uid) {
  postRef.transaction((post) => {
    if (post) {
      if (post.stars && post.stars[uid]) {
        post.starCount--;
        post.stars[uid] = null;
      } else {
        post.starCount++;
        if (!post.stars) {
          post.stars = {};
        }
        post.stars[uid] = true;
      }
    }
    return post;
  });
}

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

תוספות בצד השרת האטומי

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

function addStar(uid, key) {
  const updates = {};
  updates[`posts/${key}/stars/${uid}`] = true;
  updates[`posts/${key}/starCount`] = firebase.database.ServerValue.increment(1);
  updates[`user-posts/${key}/stars/${uid}`] = true;
  updates[`user-posts/${key}/starCount`] = firebase.database.ServerValue.increment(1);
  firebase.database().ref().update(updates);
}

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

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

עבודה עם נתונים לא מקוונים

אם לקוח מאבד את חיבור הרשת שלו, האפליקציה שלך תמשיך לפעול כראוי.

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

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

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

נידבר יותר על התנהגות לא מקוונת למידע נוסף על מקוון ויכולות מחוברות ..

הצעדים הבאים