2017-07-23 4 views
12

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

query.observeSingleEvent(of: .childAdded, with: { snapshot in 

      print(snapshot) 

      let indexPaths = self.messages.enumerated().map { 
       IndexPath(row: $0.0, section: 0) 
      } 

      guard let messagesDict = snapshot.value as? [String:AnyObject] else { return } 
      guard let sender = messagesDict["sender"] as? String else { return } 
      guard let text = messagesDict["text"] as? String else { return } 
      guard let timestamp = messagesDict["timestamp"] as? Int else { return } 

      let message = Message.init(key: snapshot.key, sender: sender as! String, text: text as! String, timestamp: timestamp) 

      self.messages.append(message) 

      self.tableView.reloadData() 
     }) 

po messagesDict रिटर्न डेटा:

▿ 1 element 
    ▿ 0 : 2 elements 
    - key : "-KotqLUUucaRagTRt967" 
    ▿ value : 3 elements 
     ▿ 0 : 2 elements 
     - key : sender 
     - value : eGTYRSo81JefgasYLRHUFHUTnEC3 
     ▿ 1 : 2 elements 
     - key : text 
     - value : test 
     ▿ 2 : 2 elements 
     - key : timestamp 
     - value : 1499914135546 

एप्लिकेशन अगले ब्रेकप्वाइंट जहां के लिए हो जाता है मैंने guard let sender सेट किया है लेकिन ऐप रिटर्न हिट करता है और कोड के बाकी ब्लॉक को निष्पादित करता है। मैं प्रेषक, टेक्स्ट और टाइमस्टैम्प तत्वों को सही तरीके से कैसे एक्सेस करूं ताकि मैं उन्हें चर के लिए सेट कर सकूं और उन्हें अपनी तालिका के लिए सरणी में संग्रहीत कर सकूं?

किसी भी मदद की सराहना की जाएगी। मैं थोड़ी देर के लिए इस पर अटक गया हूं और मैं आंखों की एक और जोड़ी का उपयोग कर सकता हूं!

धन्यवाद !!

अतिरिक्त जानकारी:

क्वेरी:

let query = rootRef.child("chat-messages/\(chatKey)")

डेटाबेस संरचना:

{ 
    "chat-messages" : { 
    "-KotqKI4zF9cS5XMR9WU" : { 
     "-KotqLUUucaRagTRt967" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499914135546 
     } 
    }, 
    "-KotqvBoFFzOTY6Q1fO7" : { 
     "-KotqwGAJ85NuAp-Lh3Z" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499914290279 
     } 
    }, 
    "-KotsNgF0ou5MIDn2l5K" : { 
     "-KotsOSXw7OS_3xuXZgP" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499914671997 
     }, 
     "-KotsPqrCpipMLulNNFl" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test44", 
     "timestamp" : 1499914677715 
     } 
    }, 
    "-Kotsv1Vv19dEF2q7XQu" : { 
     "-KotsvYO9JvLY8gdTnA0" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499914811675 
     }, 
     "-KotsvxKXzIwbyvbwLPp" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499914813335 
     }, 
     "-Kotsw9vLiEf6KquU__e" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499914814205 
     }, 
     "-KotswHnzmfkEXih1O7y" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499914814709 
     }, 
     "-KotszHKBt254jZnUMAl" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test46456", 
     "timestamp" : 1499914826967 
     } 
    }, 
    "-KoyheS01YxWExSNxl_H" : { 
     "-Koyhf3G-FPEDrxQOcpU" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499995746607 
     } 
    }, 
    "-Koyjc_aBaF1kFE-8Bll" : { 
     "-Koyjd9PnO6sPOhS7P27" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499996263096 
     }, 
     "-KoyjdzSEi5twTVQMGOu" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499996266491 
     }, 
     "-Koyje2C9E524kV7nhLY" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1499996266730 
     } 
    }, 
    "-KpfUGw45F1FU2IrR87A" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1500746948396 
    }, 
    "-KpfUHQGuTDi4yZutS5K" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1500746950368 
    }, 
    "-KpfUHdSXeTzauATsDAP" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "test", 
     "timestamp" : 1500746951277 
    }, 
    "-Kpfia0fXsoqpRtIr1kU" : { 
     "sender" : "eGTYRSo81JefgasYLRHUFHUTnEC3", 
     "text" : "gerg", 
     "timestamp" : 1500750962815 
    } 
    }, 
    "chat-participants" : { 
    "-KotqKI4zF9cS5XMR9WU" : { 
     "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "username" : "tester" 
     } 
    }, 
    "-KotqvBoFFzOTY6Q1fO7" : { 
     "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "username" : "tester" 
     } 
    }, 
    "-KotsNgF0ou5MIDn2l5K" : { 
     "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "username" : "tester" 
     } 
    }, 
    "-Kotsv1Vv19dEF2q7XQu" : { 
     "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "username" : "tester" 
     } 
    }, 
    "-KoyheS01YxWExSNxl_H" : { 
     "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "username" : "tester" 
     } 
    }, 
    "-Koyjc_aBaF1kFE-8Bll" : { 
     "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "username" : "tester" 
     } 
    }, 
    "-KpfLBjQdPiX2kSrl1yF" : { 
     "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "username" : "tester" 
     } 
    } 
    }, 
    "chats" : { 
    "-KotqKI4zF9cS5XMR9WU" : { 
     "currentName" : "test", 
     "date" : 1499914130657 
    }, 
    "-KotqvBoFFzOTY6Q1fO7" : { 
     "currentName" : "test", 
     "date" : 1499914285904 
    }, 
    "-KotsNgF0ou5MIDn2l5K" : { 
     "currentName" : "test", 
     "date" : 1499914668844 
    }, 
    "-Kotsv1Vv19dEF2q7XQu" : { 
     "currentName" : "test", 
     "date" : 1499914809570 
    }, 
    "-KoyheS01YxWExSNxl_H" : { 
     "currentName" : "test", 
     "date" : 1499995744095 
    }, 
    "-Koyjc_aBaF1kFE-8Bll" : { 
     "currentName" : "test", 
     "date" : 1499996260740 
    }, 
    "-KpfLBjQdPiX2kSrl1yF" : { 
     "currentName" : "test3222", 
     "date" : 1500744567786 
    } 
    }, 
    "user-chats" : { 
    "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "-KotqKI4zF9cS5XMR9WU" : { 
     "chatKey" : "-KotqKI4zF9cS5XMR9WU", 
     "currentName" : "test" 
     }, 
     "-KotqvBoFFzOTY6Q1fO7" : { 
     "chatKey" : "-KotqvBoFFzOTY6Q1fO7", 
     "currentName" : "test" 
     }, 
     "-KotsNgF0ou5MIDn2l5K" : { 
     "chatKey" : "-KotsNgF0ou5MIDn2l5K", 
     "currentName" : "test" 
     }, 
     "-Kotsv1Vv19dEF2q7XQu" : { 
     "chatKey" : "-Kotsv1Vv19dEF2q7XQu", 
     "currentName" : "test" 
     }, 
     "-KoyheS01YxWExSNxl_H" : { 
     "chatKey" : "-KoyheS01YxWExSNxl_H", 
     "currentName" : "test" 
     }, 
     "-Koyjc_aBaF1kFE-8Bll" : { 
     "chatKey" : "-Koyjc_aBaF1kFE-8Bll", 
     "currentName" : "test" 
     }, 
     "-KpfLBjQdPiX2kSrl1yF" : { 
     "chatKey" : "-KpfLBjQdPiX2kSrl1yF", 
     "currentName" : "test3222" 
     } 
    } 
    }, 
    "user-friends" : { 
    "36HDn5XyxjMCcMluJJ9KPBOCDMm1" : { 
     "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "username" : "tester" 
     } 
    }, 
    "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "36HDn5XyxjMCcMluJJ9KPBOCDMm1" : { 
     "username" : "tester2" 
     } 
    } 
    }, 
    "user-invites" : { 
    "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "36HDn5XyxjMCcMluJJ9KPBOCDMm1" : { 
     "username" : "tester2" 
     } 
    } 
    }, 
    "users" : { 
    "36HDn5XyxjMCcMluJJ9KPBOCDMm1" : { 
     "email" : "[email protected]", 
     "username" : "tester2" 
    }, 
    "eGTYRSo81JefgasYLRHUFHUTnEC3" : { 
     "email" : "[email protected]", 
     "username" : "tester" 
    } 
    } 
} 
+0

आपकी क्वेरी क्या है? और आपकी डेटाबेस संरचना? – Pipiks

+0

इस पर आपकी मदद के लिए धन्यवाद! मैंने क्वेरी और डेटाबेस संरचना को शामिल करने के लिए प्रश्न संपादित किया। – winston

+0

@freeman मैंने कुछ दिन पहले एक सुझाए गए समाधान को जोड़ा - समस्या को हल करें या अभी भी समस्याएं हैं? – Yasir

उत्तर

3

की तरह आपका शब्दकोश नज़र:

▿ 1 element 
    ▿ 0 : 2 elements 
    - key : "-KotqLUUucaRagTRt967" 
    ▿ value : 3 elements 
     ▿ 0 : 2 elements 
     - key : sender 
     - value : eGTYRSo81JefgasYLRHUFHUTnEC3 
     ▿ 1 : 2 elements 
     - key : text 
     - value : test 
     ▿ 2 : 2 elements 
     - key : timestamp 
     - value : 1499914135546 

लेकिन वास्तव में यह की तरह दिखना चाहिए (आप शब्दकोश पर पहुंचना चाहते हैं [ "प्रेषक"]):

▿ 2 elements 
    ▿ 0 : 2 elements 
    - key : sender 
    - value : eGTYRSo81JefgasYLRHUFHUTnEC3 
    ▿ 1 : 2 elements 
    - key : text 
    - value : test 
    ▿ 2 : 2 elements 
    - key : timestamp 
    - value : 1499914135546 

पहले समाधान:

आपको अपनी क्वेरी में .child ("- KotqLUUucaRagTRt967") जोड़ने की जरूरत है।

या

दूसरा समाधान:

आप ऐसा ही कुछ करने की जरूरत है:

query.observe(.childAdded, with: { snapshot in 
    for child in snapshot.children { 
     guard let value = child.value as? NSDictionary else { 
      return 
     } 

     guard let sender = value["sender"] as? String else { 
      return 
     } 

     // You can user the sender 
    } 
}) 

अद्यतन:

query.observe(.childAdded, with: { snapshot in 
    for child in snapshot.children.allObjects as! [FIRDataSnapshot] { 
     if let value = child.value as? [String:Any], let sender = value["sender"] as? String { 
      // You can user the sender 
     } 
    } 
}) 

नोट

मैं observeSingleEvent प्रतिस्थापित साथ निरीक्षण, के रूप में फ्रैंक वैन Puffelen ने कहा, यह के लिए एक असामान्य संयोजन है।बच्चे जोड़ा गया।

+0

धन्यवाद! मुझे त्रुटि मिल रही है 'प्रकार का मूल्य कोई सदस्य मान नहीं है'। यह 'value = child.value' पर त्रुटियां है। कोई विचार? – winston

+0

@freeman इससे पहले कि आप 'मूल्य = child.value'' गार्ड let' शामिल करना न भूलें किया था? –

+0

@RajatKhare हाँ यह अभी भी इस लाइन पर त्रुटियों गार्ड मूल्य = child.value के रूप में जाने '? NSDictionary अन्य {वापसी} '। एक्सकोड ने इसे बदलने के लिए सुझाव दिया है 'गार्ड को मूल्य = (बच्चे को AnyObject के रूप में) .value के रूप में? else {वापसी} 'लेकिन फिर उस त्रुटि फेंकता NSDictionary' मान' – winston

4

मुझे नहीं लगता कि आप एक ChildAdded हैंडलर चाहते हैं, तो मैं एक observeSingleEvent उदाहरण के साथ जाने के बाद से आप चलाता बिना उस समय डेटाबेस से डेटा क्वेरी करना चाहते हैं। जब आप एक निरीक्षण SingleEvent का उपयोग करते हैं, तो डेटाबेस को सिंक में रखना महत्वपूर्ण है। मैं नीचे दिए गए कोड का उपयोग कर की सिफारिश करेंगे:

query.keepSynched(true) //keeps data in sync with database, if you have data persistince on in your appDelegate 
query.observeSingleEvent(of: .value, with: { (snapshot) in //notice the changed here 
      print(snapshot) 
      //Since you want to loop again because there could be multiple 
      //messages in that chatroom which all have a unique ID, do this loop: 
      let enumerator = snapshot.children 
      while let rest = enumerator.nextObject() as? FIRDataSnapshot { 
       //this is 1 single message here 
       let values = rest.value as? NSDictionary 
       for (key, value) in values{ 
       print("Key: \(key), value: \(value)") 
       } 
       //lets say you want to check if there is a value with a key named "text": 
      let textUser = values?["text"] as? String ?? "No text found" 
       //providing a default value if there is no text. You could leave it empty, than it is nil (not recommend) 
       //Not only is this a lot more readable, I do not use force unwrapping so your app 
       //cannot cause an exception. 

       //Get more values from the dictionary as I did with textUser 
       //Initialize message than here. You will see you do not need to force unwrap anything :D 
       } 

      } 

     }) 
+0

की जाँच करें "आप और Pipiks एक ChildAdded के साथ एक observeSingleEvent गठबंधन, इस दोनों एक साथ नहीं जाते" हालांकि यह एक असामान्य संयोजन है, वहाँ कोई है तकनीकी कारण इन्हें संयुक्त नहीं किया जा सकता है। –

+0

सहमत हैं, यह नहीं देखते कि आप एक भी घटना और बच्चे को क्यों जोड़ नहीं सकते? – Yasir

+0

@Yasir मुझे यकीन नहीं था, यही कारण है कि "मुझे लगता है ??!"। दस्तावेज़ों से मैंने उस बच्चे को पढ़ा है जब हर बार एक नया बच्चा जोड़ा जाता है तो जोड़ा जाता है। एक निरीक्षण SingleEvent उस समय डेटा को पढ़ेगा जैसा कि उस समय है। मैंने सोचा कि दो एक साथ काम नहीं करेंगे, लेकिन फ्रैंक ने मुझे पहले से ही सही कर दिया है, मैं उस भाग को संपादित कर दूंगा। –

3

रूप Pipiks बताया गया है, आपकी समस्या यह है कि आप एक स्तर दिए गए डेटा की तुलना में अधिक पर अलग-अलग संदेश विवरण तक पहुंचने का प्रयास कर रहे हैं।

स्नैपशॉट मूल्य आप चैट संदेश, जहां शीर्ष स्तर की कुंजियों चैट संदेश चाबियाँ हैं का एक शब्दकोश दे रहा है।

query.observeSingleEvent(of: .childAdded, with: { snapshot in 

    guard let messagesDict = snapshot.value as? [String: AnyObject] else { return } 

    self.messages = messagesDict.flatMap({ (messageId: String, messageData: Any) -> Message? in 
     guard 
      let sender = messageData["sender"] as? String, 
      let text = messageData["text"] as? String, 
      let timestamp = messageData["timestamp"] as? Int, 
      let message = Message(key: messageKey, sender: sender, text: text, timestamp: timestamp) else { 
       return nil 
     } 
     return message 
    }) 

    self.tableView.reloadData() 
}) 

क्या करता Message ऑब्जेक्ट की श्रृंखला के लिए गए संदेशों के अपने शब्दकोश को मैप है: संदेशों की एक सरणी के लिए अपने दिए गए डेटा को मैप करने के लिए, मैं निम्नलिखित कोड का प्रयोग करेंगे।

मैंने किसी भी संदेश को फ़िल्टर करने के लिए एक फ्लैटमैप का उपयोग किया है जिसमें प्रेषक, टेक्स्ट या टाइमस्टैम्प मान नहीं हैं (इसलिए फ्लैटमैप [Message] ऑब्जेक्ट देता है)।

कि इस मुद्दे को हल करता है?

+0

मैं indexPaths कोड बाहर छोड़ दिया, जैसे कि यह कहीं भी प्रयोग किया जाता है यह नहीं लगता है के रूप में :) – Yasir