डेटा की सूचियों के साथ काम करना

डेटाबेस का रेफ़रंस पाना

डेटाबेस से डेटा पढ़ने या उसमें डेटा लिखने के लिए, आपको DatabaseReference के इंस्टेंस की ज़रूरत होगी:

DatabaseReference ref = FirebaseDatabase.instance.ref();

सूचियां पढ़ना और लिखना

डेटा की सूची में जोड़ना

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

push() तरीके से मिले नए डेटा के रेफ़रंस का इस्तेमाल करके, बच्चे के अपने-आप जनरेट हुए कुंजी की वैल्यू पाई जा सकती है या बच्चे के लिए डेटा सेट किया जा सकता है. push() के रेफ़रंस की .key प्रॉपर्टी में, अपने-आप जनरेट हुई कुंजी होती है.

अपने-आप जनरेट होने वाली इन कुंजियों का इस्तेमाल करके, डेटा स्ट्रक्चर को फ़्लैट किया जा सकता है. ज़्यादा जानकारी के लिए, डेटा फ़ैन-आउट का उदाहरण देखें.

उदाहरण के लिए, push() का इस्तेमाल, किसी सोशल ऐप्लिकेशन में पोस्ट की सूची में नई पोस्ट जोड़ने के लिए किया जा सकता है:

DatabaseReference postListRef = FirebaseDatabase.instance.ref("posts");
DatabaseReference newPostRef = postListRef.push();
newPostRef.set({
  // ...
});

बच्चे के इवेंट को मॉनिटर करने की अनुमति

किसी नोड के बच्चों के साथ होने वाले खास ऑपरेशन के जवाब में, चाइल्ड इवेंट ट्रिगर होते हैं. जैसे, push() तरीके से जोड़ा गया नया बच्चा या update() तरीके से अपडेट किया गया बच्चा.

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

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

final commentsRef = FirebaseDatabase.instance.ref("post-comments/$postId");
commentsRef.onChildAdded.listen((event) {
  // A new comment has been added, so add it to the displayed list.
});
commentsRef.onChildChanged.listen((event) {
  // A comment has changed; use the key to determine if we are displaying this
  // comment and if so displayed the changed comment.
});
commentsRef.onChildRemoved.listen((event) {
  // A comment has been removed; use the key to determine if we are displaying
  // this comment and if so remove it.
});

वैल्यू इवेंट सुनने की अनुमति

डेटा की सूचियों को पढ़ने के लिए, चाइल्ड इवेंट को सुनने का सुझाव दिया जाता है. हालांकि, कुछ मामलों में सूची के रेफ़रंस पर वैल्यू इवेंट को सुनना फ़ायदेमंद होता है.

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

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

myTopPostsQuery.onValue.listen((event) {
  for (final child in event.snapshot.children) {
    // Handle the post.
  }
}, onError: (error) {
  // Error.
});

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

डेटा को क्रम से लगाना और फ़िल्टर करना

Query क्लास का इस्तेमाल करके, कुंजी, वैल्यू या चाइल्ड की वैल्यू के हिसाब से क्रम से लगाया गया डेटा वापस पाया जा सकता है. क्रम से लगाए गए नतीजों को, नतीजों की किसी खास संख्या या कुंजियों या वैल्यू की किसी सीमा के हिसाब से भी फ़िल्टर किया जा सकता है.

डेटा को क्रम से लगाना

क्रम से लगाया गया डेटा वापस पाने के लिए, सबसे पहले क्रम से लगाने के तरीकों में से किसी एक को तय करें. इससे यह तय किया जा सकेगा कि नतीजों को किस क्रम में लगाया जाए:

तरीका इस्तेमाल
orderByChild() किसी खास चाइल्ड की या नेस्ट किए गए चाइल्ड पाथ की वैल्यू के हिसाब से नतीजों को क्रम से लगाएं.
orderByKey() चाइल्ड की के हिसाब से नतीजों को क्रम से लगाएं.
orderByValue() चाइल्ड वैल्यू के हिसाब से नतीजों को क्रम से लगाएं.

एक बार में, सिर्फ़ एक क्रम से लगाने के तरीके का इस्तेमाल किया जा सकता है. एक ही क्वेरी में order-by तरीके को कई बार कॉल करने पर गड़बड़ी होती है.

यहां दिए गए उदाहरण में, किसी उपयोगकर्ता की सबसे ज़्यादा स्टार वाली पोस्ट की सूची पाने का तरीका बताया गया है:

final myUserId = FirebaseAuth.instance.currentUser?.uid;
final topUserPostsRef = FirebaseDatabase.instance
    .ref("user-posts/$myUserId")
    .orderByChild("starCount");

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

orderByChild() तरीके को कॉल करने पर, बच्चे की कुंजी तय की जाती है. इससे नतीजों को क्रम से लगाया जा सकता है. इस मामले में, पोस्ट को उनके "starCount" चाइल्ड की वैल्यू के हिसाब से क्रम में लगाया जाता है. अगर आपके पास ऐसा डेटा है, तो क्वेरी को नेस्ट किए गए बच्चों के हिसाब से भी क्रम में लगाया जा सकता है:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

इस मामले में, हम अपनी सूची के एलिमेंट को metrics कुंजी के नीचे नेस्ट की गई वैल्यू के हिसाब से क्रम में लगा सकते हैं. इसके लिए, हमें अपने orderByChild() कॉल में नेस्ट किए गए चाइल्ड का रिलेटिव पाथ बताना होगा.

final mostViewedPosts =
    FirebaseDatabase.instance.ref('posts').orderByChild('metrics/views');

अन्य डेटा टाइप को क्रम से लगाने के तरीके के बारे में ज़्यादा जानने के लिए, क्वेरी के डेटा को क्रम से कैसे लगाया जाता है लेख पढ़ें.

डेटा फ़िल्टर करना

डेटा को फ़िल्टर करने के लिए, क्वेरी बनाते समय सीमा या रेंज के किसी भी तरीके को क्रम से लगाने के तरीके के साथ जोड़ा जा सकता है.

तरीका इस्तेमाल
limitToFirst() इससे नतीजों की क्रम से लगाई गई सूची की शुरुआत से, दिखाए जाने वाले आइटम की ज़्यादा से ज़्यादा संख्या सेट की जाती है.
limitToLast() इससे, क्रम से लगाए गए नतीजों की सूची के आखिर से लौटाए जाने वाले आइटम की ज़्यादा से ज़्यादा संख्या सेट की जाती है.
startAt() चुनी गई 'इसके हिसाब से क्रम लगाएं' विधि के आधार पर, दी गई कुंजी या वैल्यू से ज़्यादा या उसके बराबर आइटम दिखाएं.
startAfter() चुने गए order-by तरीके के आधार पर, दी गई कुंजी या वैल्यू से ज़्यादा आइटम दिखाएं.
endAt() चुनी गई 'क्रम से लगाएं' विधि के आधार पर, तय की गई कुंजी या वैल्यू से कम या उसके बराबर आइटम दिखाएं.
endBefore() चुनी गई 'इसके हिसाब से क्रम लगाएं' विधि के आधार पर, दी गई कुंजी या वैल्यू से कम वैल्यू वाले आइटम दिखाएं.
equalTo() चुने गए order-by तरीके के आधार पर, दी गई कुंजी या वैल्यू के बराबर आइटम दिखाएं.

order-by के तरीकों के उलट, limit या range फ़ंक्शन को एक साथ इस्तेमाल किया जा सकता है. उदाहरण के लिए, startAt() और endAt() तरीकों को एक साथ इस्तेमाल करके, नतीजों को वैल्यू की तय की गई सीमा तक सीमित किया जा सकता है.

नतीजों की संख्या सीमित करना

limitToFirst() और limitToLast() तरीकों का इस्तेमाल करके, किसी इवेंट के लिए सिंक किए जाने वाले बच्चों की ज़्यादा से ज़्यादा संख्या सेट की जा सकती है. उदाहरण के लिए, अगर आपने limitToFirst() का इस्तेमाल करके 100 की सीमा सेट की है, तो आपको शुरुआत में सिर्फ़ 100 onChildAdded इवेंट मिलेंगे. अगर आपके Firebase डेटाबेस में 100 से कम आइटम सेव हैं, तो हर आइटम के लिए onChildAdded इवेंट ट्रिगर होता है.

आइटम में बदलाव होने पर, आपको क्वेरी में शामिल होने वाले आइटम के लिए onChildAdded इवेंट और क्वेरी से बाहर निकलने वाले आइटम के लिए onChildRemoved इवेंट मिलते हैं, ताकि कुल संख्या 100 पर बनी रहे.

यहां दिए गए उदाहरण में बताया गया है कि ब्लॉगिंग की सुविधा देने वाला कोई ऐप्लिकेशन, सभी उपयोगकर्ताओं की 100 सबसे नई पोस्ट की सूची पाने के लिए क्वेरी कैसे तय करता है:

final recentPostsRef = FirebaseDatabase.instance.ref('posts').limitToLast(100);

इस उदाहरण में सिर्फ़ एक क्वेरी तय की गई है. डेटा को असल में सिंक करने के लिए, इसमें लिसनर अटैच होना चाहिए.

कुंजी या वैल्यू के हिसाब से फ़िल्टर करना

क्वेरी के लिए, आर्बिट्रेरी शुरुआती, खत्म होने, और समानता वाले पॉइंट चुनने के लिए, startAt(), startAfter(),endAt(), endBefore(), और equalTo() का इस्तेमाल किया जा सकता है. यह डेटा को पेज के हिसाब से बांटने या उन आइटम को ढूंढने के लिए काम आ सकता है जिनमें बच्चों के लिए बने प्रॉडक्ट शामिल हैं और जिनकी कोई खास वैल्यू है.

क्वेरी के डेटा को कैसे क्रम से लगाया जाता है

इस सेक्शन में बताया गया है कि Query क्लास में, ऑर्डर करने के हर तरीके से डेटा को कैसे क्रम से लगाया जाता है.

orderByChild

orderByChild() का इस्तेमाल करने पर, दी गई चाइल्ड की के हिसाब से डेटा को इस तरह क्रम में लगाया जाता है:

  1. जिन बच्चों के लिए, दी गई चाइल्ड की की null वैल्यू है वे सबसे पहले दिखते हैं.
  2. इसके बाद, चाइल्ड की तय की गई कुंजी के लिए false वैल्यू वाले बच्चे दिखते हैं. अगर कई चाइल्ड में false की वैल्यू है, तो उन्हें कुंजी के हिसाब से लेक्सिकोग्राफ़िक क्रम में लगाया जाता है.
  3. इसके बाद, चाइल्ड की तय की गई कुंजी के लिए true वैल्यू वाले बच्चे दिखते हैं. अगर कई चाइल्ड में true वैल्यू है, तो उन्हें कुंजी के हिसाब से लेक्सिकोग्राफ़िक क्रम में लगाया जाता है.
  4. इसके बाद, संख्या वाली वैल्यू वाले बच्चे आते हैं. इन्हें बढ़ते क्रम में लगाया जाता है. अगर एक से ज़्यादा चाइल्ड नोड के लिए, तय किए गए चाइल्ड नोड की संख्यात्मक वैल्यू एक जैसी है, तो उन्हें कुंजी के हिसाब से क्रम में लगाया जाता है.
  5. स्ट्रिंग, संख्याओं के बाद आती हैं और इन्हें लेक्सिकोग्राफ़िक क्रम में बढ़ते क्रम में लगाया जाता है. अगर कई बच्चों के लिए, चाइल्ड नोड की वैल्यू एक जैसी है, तो उन्हें कुंजी के हिसाब से लेक्सिकोग्राफ़िक क्रम में लगाया जाता है.
  6. ऑब्जेक्ट आखिर में आते हैं और उन्हें लेक्सिकोग्राफ़िक क्रम में, कुंजी के हिसाब से बढ़ते क्रम में लगाया जाता है.

orderByKey

अपने डेटा को क्रम से लगाने के लिए orderByKey() का इस्तेमाल करने पर, डेटा को कुंजी के हिसाब से बढ़ते क्रम में दिखाया जाता है.

  1. जिन बच्चों के पास ऐसी कुंजी होती है जिसे 32-बिट पूर्णांक के तौर पर पार्स किया जा सकता है उन्हें बढ़ते क्रम में सबसे पहले दिखाया जाता है.
  2. इसके बाद, उन बच्चों को दिखाया जाता है जिनकी कुंजी के तौर पर स्ट्रिंग वैल्यू होती है. इन्हें लेक्सिकोग्राफ़िक क्रम में बढ़ते क्रम में क्रमबद्ध किया जाता है.

orderByValue

orderByValue() का इस्तेमाल करने पर, बच्चों को उनकी वैल्यू के हिसाब से क्रम में लगाया जाता है. क्रम से लगाने के मानदंड, orderByChild() में दिए गए मानदंडों के जैसे ही होते हैं. हालांकि, इसमें किसी तय की गई चाइल्ड की के मान के बजाय, नोड के मान का इस्तेमाल किया जाता है.

लिसनर को अलग करना

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

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

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

अगले चरण