वेब पर डेटा पढ़ें और लिखें

(ज़रूरी नहीं) प्रोटोटाइप बनाना और Firebase Local Emulator Suite की मदद से टेस्ट करना

आपका ऐप्लिकेशन Realtime Database से कैसे पढ़ता है और उसमें कैसे लिखता है, इस बारे में बात करने से पहले, Realtime Database की सुविधाओं के प्रोटोटाइप बनाने और उनकी जांच करने के लिए इस्तेमाल किए जा सकने वाले टूल के बारे में बताते हैं: Firebase Local Emulator Suite. अगर आपको कोई दूसरा डेटा आज़माना है, मॉडल, आपके सुरक्षा नियमों को ऑप्टिमाइज़ करना या फिर से टारगेट करने के लिए, बैक-एंड से इंटरैक्ट करने का किफ़ायती तरीका, स्थानीय तौर पर काम करना काम हो सकता है. यह काम, लाइव सेवाओं को डिप्लॉय किए बिना किया जा सकता है.

एक Realtime Database एम्युलेटर, Local Emulator Suite का हिस्सा है, जो इससे आपका ऐप्लिकेशन, आपके डेटाबेस के एम्युलेट किए गए कॉन्टेंट और कॉन्फ़िगरेशन से इंटरैक्ट कर सकता है. जैसे: विकल्प के तौर पर, आपके एम्युलेट किए गए प्रोजेक्ट रिसोर्स (फ़ंक्शन, अन्य डेटाबेस, और सुरक्षा के नियम शामिल हैं).

Realtime Database एम्युलेटर को इस्तेमाल करने के लिए, आपको कुछ ही चरण पूरे करने होंगे:

  1. एम्युलेटर से कनेक्ट करने के लिए, अपने ऐप्लिकेशन के टेस्ट कॉन्फ़िगरेशन में कोड की एक लाइन जोड़ना.
  2. आपकी लोकल प्रोजेक्ट डायरेक्ट्री के रूट से, firebase emulators:start पर चल रहा है.
  3. Realtime Database प्लैटफ़ॉर्म का इस्तेमाल करके, अपने ऐप्लिकेशन के प्रोटोटाइप कोड से कॉल करना हमेशा की तरह SDK टूल या Realtime Database REST API का इस्तेमाल करके इंस्टॉल करें.

Realtime Database और Cloud Functions के बारे में ज़्यादा जानकारी वाला वॉकथ्रू उपलब्ध है. आपको Local Emulator Suite के बारे में जानकारी भी देखनी चाहिए.

डेटाबेस के बारे में जानकारी पाएं

डेटाबेस से डेटा पढ़ने या उसमें बदलाव करने के लिए, आपको के इंस्टेंस की ज़रूरत होगी firebase.database.Reference:

Web

import { getDatabase } from "firebase/database";

const database = getDatabase();

Web

var database = firebase.database();

डेटा सेव करना

इस दस्तावेज़ में डेटा वापस पाने के बारे में बुनियादी जानकारी दी गई है. साथ ही, इसमें डेटा को क्रम में लगाने और फ़िल्टर करने का तरीका भी बताया गया है Firebase डेटा.

Firebase डेटा को firebase.database.Reference. इस वैल्यू के लिए, लिसनर एक बार ट्रिगर होता है डेटा की शुरुआती स्थिति को फिर से बदला जा सकता है.

लिखने से जुड़ी बुनियादी कार्रवाइयां

लिखने के बुनियादी काम करने के लिए, set() का इस्तेमाल करके किसी खास प्रोजेक्ट में डेटा सेव किया जा सकता है संदर्भ दिया होता है, जो उस पाथ के किसी भी मौजूदा डेटा को बदल देता है. उदाहरण के लिए सोशल मीडिया ऐप्लिकेशन ब्लॉगिंग ऐप्लिकेशन, set() वाले किसी उपयोगकर्ता को इस तरह जोड़ सकता है:

Web

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
  });
}

Web

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

set() का इस्तेमाल करने से, तय की गई जगह का डेटा ओवरराइट हो जाता है. इसमें कोई भी चाइल्ड डेटा शामिल है नोड.

डेटा पढ़ें

वैल्यू इवेंट सुनें

किसी पाथ पर डेटा पढ़ने और बदलावों को सुनने के लिए, इवेंट को देखने के लिए onValue() का इस्तेमाल करें. इस इवेंट का इस्तेमाल, यहां कॉन्टेंट के स्टैटिक स्नैपशॉट पढ़ने के लिए किया जा सकता है दिया गया पाथ, जैसा कि वे इवेंट के समय मौजूद थे. यह तरीका एक बार ट्रिगर होता है, जब लिसनर जुड़ा होता है. इसके बाद, जब भी बच्चों के साथ-साथ डेटा में कोई बदलाव होता है, तब ट्रिगर होता है. इवेंट कॉलबैक को एक स्नैपशॉट भेजा जाता है. इसमें उस जगह का सारा डेटा होता है. इसमें चाइल्ड डेटा भी शामिल होता है. अगर कोई डेटा मौजूद नहीं है, तो स्नैपशॉट, exists() को कॉल करने पर false दिखाएगा. साथ ही, val() के कॉल करने पर null को कॉल करेगा.

निम्न उदाहरण में सोशल ब्लॉगिंग ऐप्लिकेशन डेटाबेस से किसी पोस्ट की स्टार संख्या:

Web

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);
});

Web

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

सुनने वाले को एक snapshot मिलता है, जिसमें तय किए गए इवेंट के समय, डेटाबेस में मौजूद जगह की जानकारी. डेटा वापस पाने के दौरान snapshot में, val() तरीके से.

डेटा को एक बार पढ़ें

get() की मदद से डेटा को एक बार पढ़ना

SDK टूल को डेटाबेस सर्वर के साथ इंटरैक्शन को मैनेज करने के लिए डिज़ाइन किया गया है. इससे कोई फ़र्क़ नहीं पड़ता कि ऐप ऑनलाइन है या ऑफ़लाइन.

आम तौर पर, वैल्यू इवेंट की उन तकनीकों का इस्तेमाल करना चाहिए जिनके बारे में ऊपर बताया गया है. डेटा का इस्तेमाल कर सकता है. लिसनर तकनीकें, आपके इस्तेमाल और बिलिंग को कम करती हैं. साथ ही, इन्हें इन कामों के लिए ऑप्टिमाइज़ किया जाता है: ताकि आपके उपयोगकर्ताओं को ऑनलाइन और ऑफ़लाइन होने पर बेहतरीन अनुभव मिल सके.

अगर आपको डेटा सिर्फ़ एक बार चाहिए, तो डेटाबेस से डेटा का स्नैपशॉट पाने के लिए, get() का इस्तेमाल किया जा सकता है. अगर किसी वजह से get(), सर्वर को नहीं लौटा पाता है मान है, तो क्लाइंट लोकल स्टोरेज कैश की जांच करेगा और गड़बड़ी दिखाएगा मान अब भी नहीं मिला.

get() का गलत इस्तेमाल करने से, बैंडविड्थ का इस्तेमाल बढ़ सकता है और परफ़ॉर्मेंस में गिरावट आ सकती है. हालांकि, ऊपर बताए गए तरीके से रीयल टाइम लिसनर का इस्तेमाल करके, इस समस्या से बचा जा सकता है.

Web

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);
});

Web

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() का उपयोग करके तुरंत लोकल डिस्क कैश से डेटा ले सकते हैं.

यह ऐसे डेटा के लिए फ़ायदेमंद है जिसे सिर्फ़ एक बार लोड करने की ज़रूरत होती है और इसकी उम्मीद नहीं होती लगातार बदलते रहें या लगातार सुनने की सुविधा चालू करें. उदाहरण के लिए, पिछले उदाहरणों में दिया गया ब्लॉगिंग ऐप्लिकेशन, इस तरीके का इस्तेमाल करके उपयोगकर्ता की प्रोफ़ाइल को लोड करता है. ऐसा तब होता है, जब उपयोगकर्ता कोई नई पोस्ट लिखना शुरू करता है:

Web

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
});

Web

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() को कॉल करते समय, लोअर-लेवल की चाइल्ड वैल्यू को इस तरह अपडेट किया जा सकता है कुंजी के लिए पाथ तय कर रहा है. अगर डेटा को बेहतर तरीके से स्केल करने के लिए, एक से ज़्यादा जगहों पर सेव किया गया है, तो डेटा फ़ैन-आउट का इस्तेमाल करके, उस डेटा के सभी इंस्टेंस अपडेट किए जा सकते हैं.

उदाहरण के लिए, कोई सोशल ब्लॉगिंग ऐप्लिकेशन पोस्ट बनाने के साथ-साथ उसे अपडेट भी कर सकता है उसे हाल की गतिविधि फ़ीड और पोस्ट करने वाले उपयोगकर्ता की गतिविधि फ़ीड पर इस तरह कोड दें:

Web

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

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);
}

Web

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(), दोनों को एक वैकल्पिक चरण पूरा करना होगा कॉलबैक को तब कॉल किया जाता है, जब डेटाबेस से डेटा को एक्सपोर्ट किया जाता है. अगर आपने कॉल पूरा नहीं हुआ, कॉलबैक को पास किया गया गड़बड़ी की वजह बताने वाला ऑब्जेक्ट.

Web

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...
});

Web

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() का इस्तेमाल करके, एक एपीआई कॉल में कई बच्चों के नाम मिटाएं.

Promise पाएं

यह जानने के लिए कि आपका डेटा, Firebase Realtime Database सर्वर के साथ कब शेयर होता है, आप किसी Promise. set() और update(), दोनों Promise लौटा सकते हैं. इसका इस्तेमाल तब किया जा सकता है, जब लिखें, डेटाबेस के साथ काम करता है.

लिसनर को अलग करें

आपके नंबर पर off() तरीके को कॉल करने पर, कॉलबैक हट जाते हैं Firebase डेटाबेस का रेफ़रंस.

किसी एक लिसनर को off() के लिए पैरामीटर के तौर पर पास करके, उसे हटाया जा सकता है. बिना किसी तर्क के off() को इस जगह पर कॉल करने से उस जगह के सभी लिसनर हट जाते हैं स्थान.

किसी पैरंट लिसनर पर off() को कॉल करने से, उसके चाइल्ड नोड पर रजिस्टर किए गए लिसनर अपने-आप नहीं हटते. कॉलबैक हटाने के लिए, चाइल्ड लिसनर पर भी off() को कॉल करना होगा.

डेटा को लेन-देन के तौर पर सेव करें

ऐसे डेटा के साथ काम करते समय जिसमें एक साथ गड़बड़ी हो सकती है जैसे कि इंंक्रीमेंटल काउंटर को शामिल किया है, तो लेन-देन की कार्रवाई. आप इस कार्रवाई को एक अपडेट फ़ंक्शन और एक वैकल्पिक पूरा कॉलबैक. अपडेट फ़ंक्शन, डेटा की मौजूदा स्थिति को इस तरह लेता है तर्क के साथ हल करता है और वह नई मनचाहा स्थिति देता है, जिसे आप लिखना चाहते हैं. अगर आपने आपकी नई वैल्यू के लागू होने से पहले, कोई दूसरा क्लाइंट उस जगह का नाम लिखता है लिखा जाता है, तो आपका अपडेट फ़ंक्शन नए वर्तमान मान के साथ फिर से कॉल किया जाता है और लिखने का फिर से प्रयास किया जाता है.

उदाहरण के लिए, सोशल ब्लॉगिंग ऐप्लिकेशन के उदाहरण में, उपयोगकर्ताओं को पोस्ट पर स्टार देने और हटाने की अनुमति दी जा सकती है. साथ ही, इस तरह से यह भी ट्रैक किया जा सकता है कि किसी पोस्ट को कितने स्टार मिले हैं:

Web

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;
  });
}

Web

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;
  });
}

लेन-देन का इस्तेमाल करने पर, अगर एक से ज़्यादा स्टार दिए गए हैं, तो स्टार काउंट गलत नहीं होगा उपयोगकर्ताओं ने एक ही समय पर एक ही पोस्ट पर स्टार का निशान लगाया या क्लाइंट के पास पुराना डेटा था. अगर लेन-देन अस्वीकार कर दिया जाता है, तो सर्वर क्लाइंट को मौजूदा वैल्यू दिखाता है. इसके बाद, क्लाइंट अपडेट की गई वैल्यू के साथ लेन-देन फिर से करता है. यह तब तक दोहराया जाता है, जब तक लेन-देन स्वीकार नहीं हो जाता या आप लेन-देन को रद्द नहीं कर देते.

ऐटमिक सर्वर-साइड इंक्रीमेंट

ऊपर दिए गए इस्तेमाल के उदाहरण में, हम डेटाबेस में दो वैल्यू लिख रहे हैं: पोस्ट को स्टार देने/अनस्टार करने वाले उपयोगकर्ता का आईडी और स्टार की संख्या में हुई बढ़ोतरी. अगर हमें पहले से पता है कि उपयोगकर्ता पोस्ट को स्टार कर रहा है, तो हम लेन-देन के बजाय, एटॉमिक इंक्रीमेंट ऑपरेशन का इस्तेमाल कर सकते हैं.

Web

function addStar(uid, key) {
  import { getDatabase, increment, ref, update } from "firebase/database";
  const dbRef = ref(getDatabase());

  const updates = {};
  updates[`posts/${key}/stars/${uid}`] = true;
  updates[`posts/${key}/starCount`] = increment(1);
  updates[`user-posts/${key}/stars/${uid}`] = true;
  updates[`user-posts/${key}/starCount`] = increment(1);
  update(dbRef, updates);
}

Web

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 क्लाइंट उस डेटा को रिमोट डेटाबेस के सर्वर और अन्य क्लाइंट के साथ "बेहतरीन तरीके" से सिंक करता है.

इस वजह से, डेटाबेस में मौजूद सभी फ़ंक्शन, लोकल इवेंट को ट्रिगर करते हैं किसी भी तरह का डेटा सर्वर पर सेव किया जाता है. इसका मतलब है कि आपका ऐप्लिकेशन फिर चाहे वह नेटवर्क में लगने वाले समय या कनेक्टिविटी की परवाह किए बिना रिस्पॉन्सिव हो.

कनेक्टिविटी वापस आने के बाद, आपके ऐप्लिकेशन को ज़रूरत के मुताबिक इवेंट दिखाए जाते हैं, ताकि क्लाइंट बिना किसी परेशानी के सर्वर की मौजूदा स्थिति के साथ सिंक हो जाए कोई कस्टम कोड लिखें.

हम ऑफ़लाइन व्यवहार के बारे में ऑनलाइन और ऑफ़लाइन सुविधाओं के बारे में ज़्यादा जानें..

अगले चरण