इस दस्तावेज़ में, Firebase में डेटा की सूचियों के साथ काम करने के बारे में बताया गया है. Firebase डेटा को पढ़ने और उसमें बदलाव करने के बुनियादी तरीकों के बारे में जानने के लिए, Android पर डेटा पढ़ना और उसमें बदलाव करना लेख पढ़ें.
DatabaseReference पाना
डेटाबेस से डेटा पढ़ने और उसमें डेटा लिखने के लिए, आपके पास DatabaseReference
का कोई इंस्टेंस होना चाहिए:
Kotlin+KTX
private lateinit var database: DatabaseReference // ... database = Firebase.database.reference
Java
private DatabaseReference mDatabase; // ... mDatabase = FirebaseDatabase.getInstance().getReference();
सूचियों को पढ़ना और उनमें बदलाव करना
डेटा की सूची में जोड़ना
कई उपयोगकर्ताओं वाले ऐप्लिकेशन में, सूची में डेटा जोड़ने के लिए push()
तरीके का इस्तेमाल करें.
push()
तरीका, तय किए गए Firebase रेफ़रंस में हर बार नया चाइल्ड जोड़ने पर एक यूनीक कुंजी जनरेट करता है. सूची में मौजूद हर नए एलिमेंट के लिए, अपने-आप जनरेट हुई इन कुंजियों का इस्तेमाल करके, कई क्लाइंट एक ही समय पर एक ही जगह पर चाइल्ड जोड़ सकते हैं. ऐसा करने पर, डेटा को लिखने में कोई समस्या नहीं होती. push()
से जनरेट किया गया यूनीक पासकोड, टाइमस्टैंप पर आधारित होता है. इसलिए, सूची के आइटम अपने-आप समय के हिसाब से क्रम में लग जाते हैं.
push()
तरीके से मिले नए डेटा के रेफ़रंस का इस्तेमाल करके, चाइल्ड की अपने-आप जनरेट हुई कुंजी की वैल्यू पाई जा सकती है या चाइल्ड के लिए डेटा सेट किया जा सकता है. push()
रेफ़रंस पर getKey()
को कॉल करने से, अपने-आप जनरेट हुई कुंजी की वैल्यू दिखती है.
अपने-आप जनरेट हुई इन कुंजियों का इस्तेमाल करके, डेटा स्ट्रक्चर को आसानी से फ़्लैट किया जा सकता है. ज़्यादा जानकारी के लिए, डेटा फ़ैन-आउट का उदाहरण देखें.
बच्चों के लिए बने इवेंट सुनना
सूचियों के साथ काम करते समय, आपके ऐप्लिकेशन को एक ऑब्जेक्ट के लिए इस्तेमाल किए गए वैल्यू इवेंट के बजाय, चाइल्ड इवेंट सुनने चाहिए.
चाइल्ड इवेंट, किसी ऑपरेशन से किसी नोड के चाइल्ड पर होने वाले खास ऑपरेशन के जवाब में ट्रिगर होते हैं. जैसे, push()
तरीके से जोड़ा गया नया चाइल्ड या updateChildren()
तरीके से अपडेट किया गया चाइल्ड.
इनमें से हर एक, डेटाबेस में किसी खास नोड में होने वाले बदलावों को सुनने के लिए काम का हो सकता है.
DatabaseReference
पर चाइल्ड इवेंट सुनने के लिए, एक
ChildEventListener
अटैच करें:
श्रोता | इवेंट कॉलबैक | आम तौर पर इस्तेमाल |
---|---|---|
ChildEventListener
| onChildAdded() |
आइटम की सूचियां वापस पाएं या आइटम की सूची में जोड़े गए आइटम सुनें.
यह कॉलबैक, हर मौजूदा चाइल्ड के लिए एक बार ट्रिगर होता है. इसके बाद, तय किए गए पाथ में हर बार नया चाइल्ड जोड़े जाने पर, यह फिर से ट्रिगर होता है. Listener को भेजे गए DataSnapshot में,
नए बच्चे का डेटा होता है.
|
onChildChanged() |
सूची में मौजूद आइटम में होने वाले बदलावों को सुनना. जब भी किसी चाइल्ड नोड में बदलाव किया जाता है, तो यह इवेंट ट्रिगर होता है. इसमें चाइल्ड नोड के वंशजों में किए गए बदलाव भी शामिल हैं. इवेंट के लिसनर को पास किए गए DataSnapshot में, बच्चे का अपडेट किया गया डेटा शामिल होता है.
|
|
onChildRemoved() |
किसी सूची से आइटम हटाए जाने की जानकारी सुनना. इवेंट कॉलबैक में पास किए गए
DataSnapshot में, हटाए गए बच्चे का डेटा होता है.
|
|
onChildMoved() |
किसी सूची में आइटम के क्रम में होने वाले बदलावों को सुनना.
जब भी किसी अपडेट की वजह से चाइल्ड के क्रम में बदलाव होता है, तो onChildChanged()
कॉलबैक ट्रिगर होने पर यह इवेंट ट्रिगर होता है.
इसका इस्तेमाल, orderByChild या orderByValue के क्रम में लगाए गए डेटा के साथ किया जाता है.
|
उदाहरण के लिए, कोई सोशल ब्लॉगिंग ऐप्लिकेशन, किसी पोस्ट की टिप्पणियों में होने वाली गतिविधि को मॉनिटर करने के लिए, इन तरीकों का एक साथ इस्तेमाल कर सकता है, जैसा कि यहां दिखाया गया है:
Kotlin+KTX
val childEventListener = object : ChildEventListener { override fun onChildAdded(dataSnapshot: DataSnapshot, previousChildName: String?) { Log.d(TAG, "onChildAdded:" + dataSnapshot.key!!) // A new comment has been added, add it to the displayed list val comment = dataSnapshot.getValue<Comment>() // ... } override fun onChildChanged(dataSnapshot: DataSnapshot, previousChildName: String?) { Log.d(TAG, "onChildChanged: ${dataSnapshot.key}") // A comment has changed, use the key to determine if we are displaying this // comment and if so displayed the changed comment. val newComment = dataSnapshot.getValue<Comment>() val commentKey = dataSnapshot.key // ... } override fun onChildRemoved(dataSnapshot: DataSnapshot) { Log.d(TAG, "onChildRemoved:" + dataSnapshot.key!!) // A comment has changed, use the key to determine if we are displaying this // comment and if so remove it. val commentKey = dataSnapshot.key // ... } override fun onChildMoved(dataSnapshot: DataSnapshot, previousChildName: String?) { Log.d(TAG, "onChildMoved:" + dataSnapshot.key!!) // A comment has changed position, use the key to determine if we are // displaying this comment and if so move it. val movedComment = dataSnapshot.getValue<Comment>() val commentKey = dataSnapshot.key // ... } override fun onCancelled(databaseError: DatabaseError) { Log.w(TAG, "postComments:onCancelled", databaseError.toException()) Toast.makeText( context, "Failed to load comments.", Toast.LENGTH_SHORT, ).show() } } databaseReference.addChildEventListener(childEventListener)
Java
ChildEventListener childEventListener = new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey()); // A new comment has been added, add it to the displayed list Comment comment = dataSnapshot.getValue(Comment.class); // ... } @Override public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey()); // A comment has changed, use the key to determine if we are displaying this // comment and if so displayed the changed comment. Comment newComment = dataSnapshot.getValue(Comment.class); String commentKey = dataSnapshot.getKey(); // ... } @Override public void onChildRemoved(DataSnapshot dataSnapshot) { Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey()); // A comment has changed, use the key to determine if we are displaying this // comment and if so remove it. String commentKey = dataSnapshot.getKey(); // ... } @Override public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey()); // A comment has changed position, use the key to determine if we are // displaying this comment and if so move it. Comment movedComment = dataSnapshot.getValue(Comment.class); String commentKey = dataSnapshot.getKey(); // ... } @Override public void onCancelled(DatabaseError databaseError) { Log.w(TAG, "postComments:onCancelled", databaseError.toException()); Toast.makeText(mContext, "Failed to load comments.", Toast.LENGTH_SHORT).show(); } }; databaseReference.addChildEventListener(childEventListener);
वैल्यू इवेंट के लिए सुनना
डेटा की सूचियों को पढ़ने के लिए, ChildEventListener
का इस्तेमाल करने का सुझाव दिया जाता है. हालांकि, कुछ मामलों में सूची के रेफ़रंस में ValueEventListener
अटैच करना फ़ायदेमंद होता है.
डेटा की सूची में ValueEventListener
अटैच करने पर, डेटा की पूरी सूची एक DataSnapshot
के तौर पर दिखेगी. इसके बाद, अलग-अलग बच्चों को ऐक्सेस करने के लिए, इस सूची को लूप किया जा सकता है.
अगर क्वेरी के लिए सिर्फ़ एक मैच है, तब भी स्नैपशॉट एक सूची होती है; इसमें सिर्फ़ एक आइटम होता है. आइटम को ऐक्सेस करने के लिए, आपको नतीजे पर बार-बार क्लिक करना होगा:
Kotlin+KTX
// My top posts by number of stars myTopPostsQuery.addValueEventListener(object : ValueEventListener { override fun onDataChange(dataSnapshot: DataSnapshot) { for (postSnapshot in dataSnapshot.children) { // TODO: handle the post } } override fun onCancelled(databaseError: DatabaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()) // ... } })
Java
// My top posts by number of stars myTopPostsQuery.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { // TODO: handle the post } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } });
यह पैटर्न तब मददगार हो सकता है, जब आपको अतिरिक्त onChildAdded
इवेंट के लिए सुनने के बजाय, एक ही ऑपरेशन में किसी सूची के सभी बच्चों को फ़ेच करना हो.
लिसनर को अलग करना
कॉलबैक हटाने के लिए, अपने Firebase डेटाबेस रेफ़रंस पर removeEventListener()
तरीके को कॉल करें.
अगर किसी डेटा लोकेशन में किसी लिसनर को कई बार जोड़ा गया है, तो हर इवेंट के लिए उसे कई बार कॉल किया जाता है. साथ ही, उसे पूरी तरह से हटाने के लिए, आपको उसे उतनी ही बार डिटैच करना होगा.
किसी पैरंट लिसनर पर removeEventListener()
को कॉल करने से, उसके चाइल्ड नोड पर रजिस्टर किए गए लिसनर अपने-आप नहीं हटते. कॉलबैक हटाने के लिए, चाइल्ड लिसनर पर भी removeEventListener()
को कॉल करना होगा.
डेटा को क्रम से लगाना और फ़िल्टर करना
Realtime Database Query
क्लास का इस्तेमाल करके, क्रम से लगाए गए डेटा को ऐक्सेस किया जा सकता है. जैसे, कुंजी, वैल्यू या चाइल्ड की वैल्यू के हिसाब से. क्रम में लगाए गए नतीजों को, किसी खास संख्या के नतीजों या कुंजियों या वैल्यू की सीमा के हिसाब से भी फ़िल्टर किया जा सकता है.
डेटा को क्रम से लगाना
क्रम से लगाए गए डेटा को वापस पाने के लिए, क्रम से लगाने के लिए इनमें से किसी एक तरीके का इस्तेमाल करें, ताकि यह तय किया जा सके कि नतीजों को किस क्रम में लगाया जाए:
तरीका | इस्तेमाल |
---|---|
orderByChild() |
किसी खास चाइल्ड की की या नेस्ट किए गए चाइल्ड पाथ की वैल्यू के हिसाब से नतीजों को क्रम में लगाएं. |
orderByKey()
| नतीजों को चाइल्ड बटन के हिसाब से क्रम में लगाएं. |
orderByValue() |
नतीजों को चाइल्ड वैल्यू के हिसाब से क्रम में लगाएं. |
एक बार में, क्रम से लगाने के लिए सिर्फ़ एक तरीके का इस्तेमाल किया जा सकता है. एक ही क्वेरी में, क्रम से लगाने के तरीके को कई बार कॉल करने पर गड़बड़ी का मैसेज मिलता है.
इस उदाहरण में, किसी उपयोगकर्ता की सबसे लोकप्रिय पोस्ट की सूची को सितारों की संख्या के हिसाब से क्रम से लगाने का तरीका बताया गया है:
Kotlin+KTX
// My top posts by number of stars val myUserId = uid val myTopPostsQuery = databaseReference.child("user-posts").child(myUserId) .orderByChild("starCount") myTopPostsQuery.addChildEventListener(object : ChildEventListener { // TODO: implement the ChildEventListener methods as documented above // ... })
Java
// My top posts by number of stars String myUserId = getUid(); Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId) .orderByChild("starCount"); myTopPostsQuery.addChildEventListener(new ChildEventListener() { // TODO: implement the ChildEventListener methods as documented above // ... });
यह एक ऐसी क्वेरी तय करती है जिसे चाइल्ड लिसनर के साथ जोड़ने पर, क्लाइंट को उपयोगकर्ता के पोस्ट के साथ सिंक किया जाता है. यह सिंक, डेटाबेस में मौजूद पाथ से किया जाता है. यह सिंक, उपयोगकर्ता के User-ID के आधार पर किया जाता है. साथ ही, हर पोस्ट को मिले स्टार की संख्या के हिसाब से क्रम में लगाया जाता है. आईडी को इंडेक्स कुंजियों के तौर पर इस्तेमाल करने की इस तकनीक को डेटा फ़ैन आउट कहा जाता है. इस बारे में ज़्यादा जानने के लिए, अपना डेटाबेस व्यवस्थित करना लेख पढ़ें.
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()
कॉल में नेस्ट किए गए चाइल्ड के रिलेटिव पाथ की जानकारी देनी होगी.
Kotlin+KTX
// Most viewed posts val myMostViewedPostsQuery = databaseReference.child("posts") .orderByChild("metrics/views") myMostViewedPostsQuery.addChildEventListener(object : ChildEventListener { // TODO: implement the ChildEventListener methods as documented above // ... })
Java
// Most viewed posts Query myMostViewedPostsQuery = databaseReference.child("posts") .orderByChild("metrics/views"); myMostViewedPostsQuery.addChildEventListener(new ChildEventListener() { // TODO: implement the ChildEventListener methods as documented above // ... });
अन्य डेटा टाइप को क्रम से लगाने के तरीके के बारे में ज़्यादा जानने के लिए, क्वेरी डेटा को क्रम से लगाने का तरीका लेख पढ़ें.
डेटा फ़िल्टर करना
डेटा को फ़िल्टर करने के लिए, क्वेरी बनाते समय, सीमित या रेंज वाले किसी भी तरीके को क्रम से लगाने के तरीके के साथ जोड़ा जा सकता है.
तरीका | इस्तेमाल |
---|---|
limitToFirst() |
इससे, क्रम से लगाई गई नतीजों की सूची में सबसे पहले से दिखाए जाने वाले आइटम की ज़्यादा से ज़्यादा संख्या तय की जाती है. |
limitToLast() |
क्रम से लगाए गए नतीजों की सूची के आखिर से दिखाए जाने वाले आइटम की ज़्यादा से ज़्यादा संख्या सेट करता है. |
startAt() |
चुने गए क्रम के तरीके के आधार पर, तय की गई कुंजी या वैल्यू से ज़्यादा या उसके बराबर वाले आइटम दिखाता है. |
startAfter() |
चुने गए क्रम के तरीके के आधार पर, तय की गई कुंजी या वैल्यू से ज़्यादा आइटम दिखाता है. |
endAt() |
चुने गए क्रम के तरीके के आधार पर, तय की गई कुंजी या वैल्यू से कम या उसके बराबर वाले आइटम दिखाता है. |
endBefore() |
चुने गए क्रम के तरीके के आधार पर, तय की गई कुंजी या वैल्यू से कम आइटम दिखाता है. |
equalTo() |
चुने गए क्रम के हिसाब से, तय की गई कुंजी या वैल्यू के बराबर आइटम दिखाता है. |
क्रम से लगाने के तरीकों के उलट, कई सीमाएं या रेंज फ़ंक्शन जोड़े जा सकते हैं.
उदाहरण के लिए, नतीजों को वैल्यू की तय सीमा तक सीमित करने के लिए, startAt()
और endAt()
तरीकों को जोड़ा जा सकता है.
क्वेरी के लिए सिर्फ़ एक मैच होने पर भी, स्नैपशॉट एक सूची ही होता है. इसमें सिर्फ़ एक आइटम होता है. आइटम को ऐक्सेस करने के लिए, आपको नतीजे को लूप करना होगा:
Kotlin+KTX
// My top posts by number of stars myTopPostsQuery.addValueEventListener(object : ValueEventListener { override fun onDataChange(dataSnapshot: DataSnapshot) { for (postSnapshot in dataSnapshot.children) { // TODO: handle the post } } override fun onCancelled(databaseError: DatabaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()) // ... } })
Java
// My top posts by number of stars myTopPostsQuery.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { // TODO: handle the post } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } });
नतीजों की संख्या सीमित करना
किसी कॉलबैक के लिए, सिंक किए जाने वाले बच्चों की ज़्यादा से ज़्यादा संख्या सेट करने के लिए, limitToFirst()
और limitToLast()
तरीकों का इस्तेमाल किया जा सकता है. उदाहरण के लिए, अगर 100 की सीमा सेट करने के लिए limitToFirst()
का इस्तेमाल किया जाता है, तो शुरुआत में आपको सिर्फ़ 100 onChildAdded()
कॉलबैक मिलते हैं. अगर आपके Firebase डेटाबेस में 100 से कम आइटम सेव हैं, तो हर आइटम के लिए एक onChildAdded()
कॉलबैक ट्रिगर होता है.
आइटम में बदलाव होने पर, आपको क्वेरी में शामिल होने वाले आइटम के लिए onChildAdded()
कॉलबैक और उससे बाहर निकलने वाले आइटम के लिए onChildRemoved()
कॉलबैक मिलते हैं, ताकि कुल संख्या 100 पर बनी रहे.
यहां दिए गए उदाहरण में दिखाया गया है कि ब्लॉगिंग ऐप्लिकेशन, सभी उपयोगकर्ताओं की सबसे हाल की 100 पोस्ट की सूची पाने के लिए क्वेरी कैसे तय करता है:
Kotlin+KTX
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys. databaseReference.child("posts").limitToFirst(100)
Java
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys Query recentPostsQuery = databaseReference.child("posts") .limitToFirst(100);
इस उदाहरण में सिर्फ़ क्वेरी के बारे में बताया गया है. डेटा को सिंक करने के लिए, उसमें लिसनर जोड़ना ज़रूरी है.
बटन या वैल्यू के हिसाब से फ़िल्टर करना
क्वेरी के लिए, शुरू और आखिर में कोई भी शब्द चुनने के लिए, startAt()
, startAfter()
, endAt()
, endBefore()
, और
equalTo()
का इस्तेमाल किया जा सकता है. यह डेटा को पेज के हिसाब से बांटने या ऐसे आइटम ढूंढने के लिए मददगार हो सकता है जिनके चाइल्ड एलिमेंट की कोई खास वैल्यू हो.
क्वेरी के डेटा को क्रम से लगाने का तरीका
इस सेक्शन में बताया गया है कि Query
क्लास में, क्रम से लगाने के हर तरीके के हिसाब से डेटा को कैसे क्रम में लगाया जाता है.
orderByChild
orderByChild()
का इस्तेमाल करने पर, उस डेटा को इस क्रम में लगाया जाता है जिसमें तय की गई चाइल्ड कुंजी शामिल होती है:
- जिन बच्चों के लिए दी गई चाइल्ड की कीमत
null
है वे सबसे पहले दिखते हैं. - इसके बाद, उन बच्चों की जानकारी दिखती है जिनके लिए तय की गई चाइल्ड कुंजी की वैल्यू
false
है. अगर एक से ज़्यादा चाइल्ड एलिमेंट की वैल्यूfalse
है, तो उन्हें की के हिसाब से लेक्सिकोग्राफ़ी के हिसाब से क्रम में लगाया जाता है. - इसके बाद, उन बच्चों की जानकारी दिखती है जिनके लिए तय की गई चाइल्ड कुंजी की वैल्यू
true
है. अगर कई चाइल्ड एलिमेंट की वैल्यूtrue
है, तो उन्हें कीवर्ड के हिसाब से, वर्णमाला के क्रम में क्रम से लगाया जाता है. - इसके बाद, संख्या वाली वैल्यू वाले बच्चे आते हैं. इन्हें बढ़ते क्रम में लगाया जाता है. अगर एक से ज़्यादा चाइल्ड के लिए, तय किए गए चाइल्ड नोड की संख्या वाली वैल्यू एक जैसी है, तो उन्हें कीवर्ड के हिसाब से क्रम में लगाया जाता है.
- स्ट्रिंग, संख्याओं के बाद आती हैं और उन्हें अंग्रेज़ी के वर्णमाला के हिसाब से, बढ़ते क्रम में लगाया जाता है. अगर कई चाइल्ड के लिए, तय किए गए चाइल्ड node की एक ही वैल्यू है, तो उन्हें कीवर्ड के हिसाब से, वर्णमाला के क्रम में लगाया जाता है.
- ऑब्जेक्ट आखिर में आते हैं और उन्हें बढ़ते क्रम में, कीवर्ड के हिसाब से क्रम में लगाया जाता है.
orderByKey
डेटा को क्रम से लगाने के लिए orderByKey()
का इस्तेमाल करने पर, डेटा को बढ़ते क्रम में दिखाया जाता है.
- जिन बच्चों की कुंजी को 32-बिट के पूर्णांक के तौर पर पार्स किया जा सकता है वे सबसे पहले दिखते हैं. साथ ही, उन्हें बढ़ते क्रम में क्रम से लगाया जाता है.
- इसके बाद, उन बच्चों की जानकारी दिखती है जिनके लिए कुंजी के तौर पर स्ट्रिंग वैल्यू दी गई है. इन बच्चों की जानकारी को वर्णमाला के क्रम में, बढ़ते क्रम में लगाया जाता है.
orderByValue
orderByValue()
का इस्तेमाल करने पर, बच्चों को उनकी वैल्यू के हिसाब से क्रम में लगाया जाता है. क्रम से लगाने की शर्तें, orderByChild()
में बताई गई शर्तों जैसी ही होती हैं. हालांकि, किसी चाइल्ड की वैल्यू के बजाय नोड की वैल्यू का इस्तेमाल किया जाता है.