Apple प्लैटफ़ॉर्म पर डेटा की सूचियों की मदद से काम करना

FIRDatabaseReference पाना

डेटाबेस से डेटा पढ़ने या उसमें डेटा लिखने के लिए, आपको FIRDatabaseReference का कोई इंस्टेंस चाहिए:

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

सूचियां पढ़ना और उनमें डेटा लिखना

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

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

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

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

चाइल्ड इवेंट के लिए लिसनर सेट अप करना

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

इवेंट टाइप आम तौर पर इस्तेमाल
FIRDataEventTypeChildAdded आइटम की सूचियां वापस पाएं या आइटम की सूची में जोड़े गए आइटम के लिए लिसनर सेट अप करें. यह इवेंट, हर मौजूदा चाइल्ड के लिए एक बार ट्रिगर होता है. इसके बाद, तय किए गए पाथ में हर बार नया चाइल्ड जोड़ने पर, यह फिर से ट्रिगर होता है. लिसनर को एक स्नैपशॉट पास किया जाता है. इसमें नए चाइल्ड का डेटा होता है.
FIRDataEventTypeChildChanged किसी सूची में मौजूद आइटम में किए गए बदलावों के लिए लिसनर सेट अप करें. यह इवेंट, चाइल्ड नोड में बदलाव होने पर ट्रिगर होता है. इसमें, चाइल्ड नोड के डिसेंडेंट में किए गए बदलाव भी शामिल होते हैं. इवेंट लिसनर को पास किए गए स्नैपशॉट में, चाइल्ड के लिए अपडेट किया गया डेटा होता है.
FIRDataEventTypeChildRemoved किसी सूची से हटाए गए आइटम के लिए लिसनर सेट अप करें. यह इवेंट, किसी इमीडिएट चाइल्ड को हटाने पर ट्रिगर होता है.कॉलबैक ब्लॉक को पास किए गए स्नैपशॉट में, हटाए गए चाइल्ड का डेटा होता है.
FIRDataEventTypeChildMoved क्रम से लगाई गई सूची में मौजूद आइटम के क्रम में किए गए बदलावों के लिए लिसनर सेट अप करें. यह इवेंट, अपडेट की वजह से चाइल्ड के क्रम में बदलाव होने पर ट्रिगर होता है. इसका इस्तेमाल, queryOrderedByChild या queryOrderedByValue के हिसाब से क्रम से लगाए गए डेटा के साथ किया जाता है.

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

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
// Listen for new comments in the Firebase database
commentsRef.observe(.childAdded, with: { (snapshot) -> Void in
  self.comments.append(snapshot)
  self.tableView.insertRows(
    at: [IndexPath(row: self.comments.count - 1, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})
// Listen for deleted comments in the Firebase database
commentsRef.observe(.childRemoved, with: { (snapshot) -> Void in
  let index = self.indexOfMessage(snapshot)
  self.comments.remove(at: index)
  self.tableView.deleteRows(
    at: [IndexPath(row: index, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
// Listen for new comments in the Firebase database
[_commentsRef
              observeEventType:FIRDataEventTypeChildAdded
              withBlock:^(FIRDataSnapshot *snapshot) {
                [self.comments addObject:snapshot];
                [self.tableView insertRowsAtIndexPaths:@[
                  [NSIndexPath indexPathForRow:self.comments.count - 1 inSection:kSectionComments]
                ]
                                      withRowAnimation:UITableViewRowAnimationAutomatic];
              }];
// Listen for deleted comments in the Firebase database
[_commentsRef
 observeEventType:FIRDataEventTypeChildRemoved
 withBlock:^(FIRDataSnapshot *snapshot) {
   int index = [self indexOfMessage:snapshot];
   [self.comments removeObjectAtIndex:index];
   [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:kSectionComments]]
                         withRowAnimation:UITableViewRowAnimationAutomatic];
 }];

वैल्यू इवेंट के लिए लिसनर सेट अप करना

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

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

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

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
[_commentsRef
              observeEventType:FIRDataEventTypeValue
              withBlock:^(FIRDataSnapshot *snapshot) {
                // Loop over children
                NSEnumerator *children = [snapshot children];
                FIRDataSnapshot *child;
                while (child = [children nextObject]) {
                  // ...
                }
              }];

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

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

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

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

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

तरीका इस्तेमाल
queryOrderedByKey नतीजों को चाइल्ड की कुंजियों के हिसाब से क्रम से लगाएं.
queryOrderedByValue नतीजों को चाइल्ड की वैल्यू के हिसाब से क्रम से लगाएं.
queryOrderedByChild नतीजों को तय की गई चाइल्ड कुंजी या नेस्ट किए गए चाइल्ड पाथ की वैल्यू के हिसाब से क्रम से लगाएं.

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

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

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
// My top posts by number of stars
let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
// My top posts by number of stars
FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"]
                                      child:[super getUid]]
                                     queryOrderedByChild:@"starCount"];

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

queryOrderedByChild तरीके को कॉल करने पर, उस चाइल्ड कुंजी को तय किया जाता है जिसके हिसाब से नतीजों को क्रम से लगाना है. इस उदाहरण में, पोस्ट को हर पोस्ट में मौजूद "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 कुंजी के तहत नेस्ट की गई वैल्यू के हिसाब से क्रम से लगा सकते हैं. इसके लिए, queryOrderedByChild कॉल में नेस्ट किए गए चाइल्ड का रिलेटिव पाथ तय करना होगा.

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

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

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

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

तरीका इस्तेमाल
queryLimitedToFirst नतीजों की क्रम से लगाई गई सूची की शुरुआत से, वापस लाए जाने वाले आइटम की ज़्यादा से ज़्यादा संख्या सेट करता है.
queryLimitedToLast नतीजों की क्रम से लगाई गई सूची के आखिर से, वापस लाए जाने वाले आइटम की ज़्यादा से ज़्यादा संख्या सेट करता है.
queryStartingAtValue तय की गई कुंजी या वैल्यू से ज़्यादा या उसके बराबर वाले आइटम वापस लाता है, यह इस बात पर निर्भर करता है कि क्रम से लगाने का कौनसा तरीका चुना गया है.
queryStartingAfterValue तय की गई कुंजी या वैल्यू से ज़्यादा वाले आइटम वापस लाता है, यह इस बात पर निर्भर करता है कि क्रम से लगाने का कौनसा तरीका चुना गया है.
queryEndingAtValue तय की गई कुंजी या वैल्यू से कम या उसके बराबर वाले आइटम वापस लाता है, यह इस बात पर निर्भर करता है कि क्रम से लगाने का कौनसा तरीका चुना गया है.
queryEndingBeforeValue तय की गई कुंजी या वैल्यू से कम वाले आइटम वापस लाता है, यह इस बात पर निर्भर करता है कि क्रम से लगाने का कौनसा तरीका चुना गया है.
queryEqualToValue तय की गई कुंजी या वैल्यू के बराबर वाले आइटम वापस लाता है. यह इस बात पर निर्भर करता है कि क्रम से लगाने का कौनसा तरीका चुना गया है.

क्रम से लगाने के तरीकों के उलट, सीमा या रेंज के कई फ़ंक्शन को जोड़ा जा सकता है. उदाहरण के लिए, नतीजों को वैल्यू की तय की गई रेंज तक सीमित करने के लिए, queryStartingAtValue और queryEndingAtValue तरीकों को जोड़ा जा सकता है.

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

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

आइटम में बदलाव होने पर, आपको उन आइटम के लिए FIRDataEventTypeChildAdded कॉलबैक मिलते हैं जो क्वेरी में शामिल होते हैं. साथ ही, उन आइटम के लिए FIRDataEventTypeChildRemoved कॉलबैक मिलते हैं जो क्वेरी से बाहर हो जाते हैं. इससे आइटम की कुल संख्या 100 बनी रहती है.

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

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

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

क्वेरी के लिए, शुरुआती, आखिरी, और इक्विवेलंस पॉइंट चुनने के लिए, queryStartingAtValue, queryStartingAfterValue, queryEndingAtValue, queryEndingBeforeValue, और queryEqualToValue का इस्तेमाल किया जा सकता है. यह डेटा को पेज में बांटने या उन आइटम को ढूंढने के लिए काम का हो सकता है जिनके चाइल्ड की कोई खास वैल्यू हो.

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

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

queryOrderedByKey

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

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

queryOrderedByValue

queryOrderedByValue का इस्तेमाल करने पर, चाइल्ड को उनकी वैल्यू के हिसाब से क्रम से लगाया जाता है. क्रम से लगाने के मानदंड, queryOrderedByChild के जैसे ही होते हैं. हालांकि, इसमें तय की गई चाइल्ड कुंजी की वैल्यू के बजाय, नोड की वैल्यू का इस्तेमाल किया जाता है.

queryOrderedByChild

queryOrderedByChild का इस्तेमाल करने पर, तय की गई चाइल्ड कुंजी वाला डेटा इस तरह क्रम से लगाया जाता है:

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

लिसनर हटाना

ViewController से बाहर निकलने पर, ऑब्ज़र्वर, डेटा सिंक करना अपने-आप बंद नहीं करते. अगर किसी ऑब्ज़र्वर को सही तरीके से नहीं हटाया जाता है, तो वह स्थानीय मेमोरी में डेटा सिंक करता रहता है. साथ ही, इवेंट हैंडलर क्लोज़र में कैप्चर किए गए सभी ऑब्जेक्ट को बनाए रखता है. इससे मेमोरी लीक हो सकती है. जब किसी ऑब्ज़र्वर की ज़रूरत न हो, तो उससे जुड़े FIRDatabaseHandle को removeObserverWithHandle तरीके में पास करके उसे हटाएं.

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

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

किसी लिसनर पर removeObserverWithHandle या removeAllObservers को कॉल करने पर, उसके चाइल्ड नोड पर रजिस्टर किए गए लिसनर अपने-आप नहीं हटते. उन्हें हटाने के लिए, आपको उन रेफ़रंस या हैंडल को भी ट्रैक करना होगा.

अगले चरण