2015-11-24 11 views
15

में काम नहीं कर रहा है, मैं अपने डेटाबेस से पूछताछ करने की कोशिश कर रहा हूं कि यह एक बाल कुंजी के आधार पर एक आदेशित सूची पुनर्प्राप्त करता है। मैं इसे निम्नानुसार करता हूं (नीचे देखें), लेकिन कुछ भी नहीं होता है, जिसका अर्थ है कि यह उसी ऑब्जेक्ट को ठीक उसी तरह देता है जैसा कि यह फ़ायरबेस डेटाबेस में संग्रहीत होता है। क्या हो रहा है?orderByChild Firebase

self.getAllProfiles = function() { 
    var qProfile = $q.defer(); 
    var ref = new Firebase(FBURL); 
    ref.child("users").orderByChild('last_update').on("value", function (snapshot) { 
     console.log(snapshot.val()) // HERE IS WHERE IT SHOULD BE ORDERED 
     qProfile.resolve(snapshot.val()); 
    }, function (errorObject) { 
     qProfile.reject(errorObject); 
    }); 
    return qProfile.promise; 
}; 

जोड़ने के लिए, मेरी उन नोड के रूप में निम्नानुसार है: एक JSON ऑब्जेक्ट

Tester: Object 
    github: Object 
    last_update: 1447732462170 
    userId: "github:12345" 
+0

क्या आप अपना डेटा अनॉर्डर्ड दिखा सकते हैं और फिर यह स्नैपशॉट के रूप में वापस आने पर कैसा दिखता है? –

+0

स्नैपशॉट – JohnAndrews

+1

यह बताने के लिए कि आप किस डेटा प्रदान की है के साथ हो रहा है मुश्किल है के साथ सवाल अपडेट किया गया। क्या आप एक जेएसबीन बना सकते हैं जो आपकी समस्या का प्रदर्शन करता है? इससे क्या हो रहा है समस्या निवारण के लिए यह बहुत आसान हो जाएगा। –

उत्तर

54

जब आप snapshot.val() कहते हैं, तुम वापस हो रही है:

users 
    /$username 
     /last_update 
     /id 
     /data 
      /profile_image 
      /display_name 

यहाँ एक स्नैपशॉट है। JSON ऑब्जेक्ट में कुंजियों का क्रम आपके ब्राउज़र द्वारा निर्धारित किया जाता है, न कि फ़ायरबेस द्वारा।

क्रम में बच्चों को पाने के लिए: snapshot.forEach() एक अतुल्यकालिक कॉल नहीं है:

self.getAllProfiles = function() { 
    var qProfile = $q.defer(); 
    var ref = new Firebase(FBURL); 
    ref.child("users").orderByChild('last_update').on("value", function (snapshot) { 
     snapshot.forEach(function(child) { 
      console.log(child.val()) // NOW THE CHILDREN PRINT IN ORDER 
     }); 
     qProfile.resolve(snapshot.val()); 
    }, function (errorObject) { 
     qProfile.reject(errorObject); 
    }); 
    return qProfile.promise; 
}; 

आप q.resolve() कॉल कहाँ है छोड़ सकते हैं।

+13

तो अगर हम की जरूरत है डेटा अनुसार क्रमबद्ध हम नई कुंजी के साथ एक नई वस्तु बनाने या किसी सरणी में प्रत्येक child.val() पर रखना होगा। क्या वह बहुत अक्षम नहीं है? – Pier

+4

क्या आप @Pier के प्रश्न का उत्तर देने का मन करेंगे? मेरे पास भी वही प्रश्न है। – Onichan

+1

@Pier यदि आपको अन्य ईवेंट प्रकार का उपयोग करने की आवश्यकता नहीं है, तो कृपया विस्तार के लिए मेरा उत्तर देखें। – user2875289

11

मुझे पता है कि इस प्रश्न का उत्तर दिया गया है और 1 साल से अधिक पुराना है, लेकिन चूंकि टिप्पणी अनुभाग में अभी भी कुछ भ्रम है, इसलिए मैं कुछ जानकारी जोड़ना चाहता हूं।

समस्या

मूल समस्या यह है कि ओपी Firebase वास्तविक समय डेटाबेस से एक बच्चे कुंजी के आधार पर एक का आदेश दिया सूची प्राप्त करना चाहते हैं, लेकिन .orderByChild('arg') अपेक्षा के अनुरूप काम नहीं करता है।

लेकिन अपेक्षित काम नहीं किया गया .orderByChild('arg'), लेकिन .on("value", callback) है। क्योंकि .on("value", callback).on("child_added", callback) जैसे अन्य ईवेंट प्रकारों से थोड़ा अलग काम करता है।

उदाहरण

कहते हैं कि हम नीचे के रूप में एक firebase वास्तविक समय डेटाबेस है:

{ 
    myData: { 
     -KYNMmYHrzLcL-OVGiTU: { 
      NO: 1, 
      image: ... 
     }, 
     -KYNMwNIz4ObdKJ7AGAL: { 
      NO: 2, 
      image: ... 
     }, 
     -KYNNEDkLpuwqQHSEGhw: { 
      NO: 3, 
      image: ... 
     }, 
    } 
} 

-

अगर हम .on("value", callback) उपयोग करते हैं, कॉलबैक() 1 बार बुलाया जाएगा, और एक वापसी ऑब्जेक्ट ऐरे 3 ऑब्जेक्ट्स।

ref.on("value", function(snapshot) { 
    console.log(snapshot.val()); 
    // Please see Frank van Puffelen's answer 
} 

enter image description here

-

अगर हम का उपयोग .on("child_added", callback), कॉलबैक() 3 बार हर बार एक वस्तु देता है बुलाया जाएगा, और वे आदेश में लौटाए जाते हैं।

ref.once("child_added", function(snapshot) { 
    console.log(snapshot.val()); 
    // The objects are returned in order, do whatever you like 
} 

enter image description here

निष्कर्ष

आप केवल firebase से आदेश डेटा लाने की जरूरत है (उदाहरण के लिए यूआई प्रारंभ करने में।) इसके बाद ref.orderByChild('arg').once("child_added", callback) सूट आप अच्छी तरह से, यह सरल और उपयोग करने के लिए आसान है।

हालांकि, अगर किसी कारण से आप ref.orderByChild('arg').on("value", callback) उपयोग करने की आवश्यकता है, तो कृपया फ्रैंक वैन Puffelen के जवाब देखें।

संदर्भ

अधिक जानकारी के लिए Firebase Document के बारे में on(eventType, callback, cancelCallbackOrContext, context) पढ़ते हैं, उनके तर्कों और उनकी वापसी मान।

एक अन्य उपयोगी दस्तावेज़: Work with Lists of Data on the Web

+1

असली कारण आप अंतर देखेंगे कि मिथ्या क्वेरी परिणाम के प्रकार है 'शब्दकोश' है, जहां 'कुंजी' (आईडी) रिकॉर्ड का शब्दकोश 'कुंजी' है। इसलिए, जेएस (ब्राउजर) इस सूची को अपनी कुंजी से टाइप करता है। है यही कारण है कि अगर यू (एक के बाद एक) 'child_added' या का उपयोग के रूप में क्वेरी 'snapshot.forEach' आप इस घटना वैकल्पिक हल करेंगे। तो यह FIB चीज़ की बजाय जेएस चीज की अधिक है। @ फ्रैंक-वैन-पफेलन का उत्तर उस कारण से अधिक सही है। –

+0

@EliLivshitz पूरी तरह से सहमत हैं। – user2875289

0

मैं आईओएस में एक ही समस्या के साथ संघर्ष किया। यदि आप स्नैपशॉट को NSDictionary ऑब्जेक्ट में कनवर्ट करते हैं, तो यह अनॉर्डर्ड सूची में परिवर्तित हो जाता है। उद्देश्य-सी संस्करण की आवश्यकता के मामले में:

[[self.refChild queryOrderedByChild:@"date_created"] 
    observeEventType:FIRDataEventTypeValue 
     withBlock:^(FIRDataSnapshot * _Nonnull snapshot) { 

    for (FIRDataSnapshot *child in snapshot.children) { 

      NSDictionary *anObject = child.value; 
      NSString *aKey   = child.key;  
    } 
}]; 
संबंधित मुद्दे