कैसे चलाने के लिए एक Firestore क्वेरी के अंदर एक नक्शा समारोह में स्विफ्ट

0

सवाल

मैं नया हूँ करने के लिए SwiftUI और Firebase और मैं कोशिश कर रहा हूँ का निर्माण करने के लिए मेरी पहली app है । मैं भंडारण के खेल में दस्तावेजों Firestore और क्षेत्रों में से एक है एक सरणी से युक्त उपयोगकर्ता आईडी के खिलाड़ियों के रूप में आप छवि में देख सकते हैं.

खेल डेटा संरचना

कहा जा रहा है कि, मैं कोशिश कर रहा हूँ करने के लिए सूची में सभी खेलों के एक उपयोगकर्ता हैं और सभी खिलाड़ियों में सूचीबद्ध प्रत्येक कोशिकाओं में से एक (क्रम महत्वपूर्ण है).

आदेश में बनाने के लिए खेलों की सूची में यूआई मैं बनाया एक GameCellListView और एक GameCellViewModel. के GameCellViewModel लोड करना चाहिए दोनों का खेल है और सरणी उपयोगकर्ताओं के अनुरूप है कि खिलाड़ियों के लिए प्रत्येक खेल के. हालांकि मैं कर रहा हूँ में सक्षम नहीं होने के लिए लोड करने के लिए उपयोगकर्ताओं की एक सरणी. मैं जाने के लिए खिलाड़ियों के माध्यम से सरणी और डेटाबेस क्वेरी के लिए प्रत्येक आईडी और संलग्न करने के लिए एक उपयोगकर्ता सरणी है, तो मैं करने में सक्षम होना चाहिए वापसी इस उपयोगकर्ता की सरणी. के बाद से मैं उपयोग कर रहा हूँ एक पाश के लिए, मैं नहीं कर सकते हैं आवंटित करने के लिए मानों की सरणी और फिर इसे वापस. मैं प्रयोग करने की कोशिश का नक्शा(), लेकिन मैं नहीं कर सकते हैं प्रदर्शन एक क्वेरी के अंदर । लक्ष्य को लोड करने के लिए है कि "सभी" var के साथ एक संरचना प्राप्त करता है कि एक खेल और उसके खिलाड़ियों GamePlayers(players: [User], game: Game)

यह देखना चाहिए की तरह कुछ कोड स्निपेट के नीचे, लेकिन उपयोगकर्ताओं सरणी हमेशा आता है खाली. इस समारोह में चलाता है पर GameCellViewModel init. मुझे आशा है कि आप मेरी समस्या समझ सकते हैं और आप पहले से धन्यवाद! पर अटक गया यह 2 सप्ताह के लिए अब

func loadData() {
        let userId = Auth.auth().currentUser?.uid
        
        db.collection("games")
            .order(by: "createdTime")
            .whereField("userId", isEqualTo: userId)
            .addSnapshotListener { (querySnapshot, error) in
            if let querySnapshot = querySnapshot {
                self.games = querySnapshot.documents.compactMap { document in
                    do {
                        let extractedGame = try document.data(as: Game.self)
                        var user = [User]()
                        let users = extractedGame!.players.map { playerId -> [User] in

                            self.db.collection("users")
                                .whereField("uid", isEqualTo: playerId)
                            .addSnapshotListener { (querySnapshot, error) in
                                guard let documents = querySnapshot?.documents else {
                                    print("No documents")
                                    return
                                }
                                user = documents.compactMap { queryDocumentSnapshot -> User? in
                                    return try? queryDocumentSnapshot.data(as: User.self)
                                    
                                }
                            }
                            return user
                        }
                        
                        self.all.append(GamePlayers(players: users.first ?? [User](), game: extractedGame!))

                        
                        return extractedGame
                    }
                    catch {
                        print(error)
                    }
                    return nil
                }
            }
        }
    }
1

सबसे अच्छा जवाब

0

वहाँ रहे हैं की एक बहुत कुछ चलती भागों में कोड और इसलिए अलग करने के लिए विफलता के अंक की आवश्यकता होगी देखकर अतिरिक्त कोड तो बस हो सकता है के बारे में पता है कि अग्रिम. उस ने कहा, यदि आप अपेक्षाकृत नए हैं के लिए Firestore या स्विफ्ट तो मैं दृढ़ता से सुझाव है कि आप पहली बार एक संभाल पाने पर इस समारोह का उपयोग कर बुनियादी वाक्यविन्यास है. एक बार जब आप के साथ आराम कर रहे भारतीय नौसेना पोत और बहिष्कार के async पाशन तो मैं सुझाव है refactoring कोड का उपयोग कर अधिक उन्नत वाक्य रचना, आप की तरह यहाँ है.

अपने कार्य प्रदर्शन करने की आवश्यकता है async काम के भीतर प्रत्येक लूप चलना (प्रत्येक दस्तावेज़). आप वास्तव में जरूरत है ऐसा करने के लिए, दो बार async काम के भीतर एक पाश के भीतर एक पाश. हो यकीन है कि यह है क्या तुम सच में चाहते हैं करने के लिए आगे बढ़ने से पहले हो सकता है क्योंकि क्लीनर तरीके शामिल हो सकते हैं जो एक और अधिक कुशल NoSQL डेटा वास्तुकला. परवाह किए बिना, के प्रयोजनों के लिए इस समारोह में, सबसे बुनियादी के साथ शुरू वाक्य रचना है के लिए काम है जो डिस्पैच समूह के साथ संगीत कार्यक्रम में के लिए-पाश । आगे बढ़ो और घोंसला ये जब तक आप यह काम कर रहा है और फिर विचार refactoring.

func loadData() {
    // Always safely unwrap the user ID and never assume it is there.
    guard let userId = Auth.auth().currentUser?.uid else {
        return
    }
    // Query the database.
    db.collection("games").whereField("userId", isEqualTo: userId).order(by: "createdTime").addSnapshotListener { (querySnapshot, error) in
        if let querySnapshot = querySnapshot {
            // We need to loop through a number of documents and perform
            // async tasks within them so instantiate a Dispatch Group
            // outside of the loop.
            let dispatch = DispatchGroup()
            
            for doc in querySnapshot.documents {
                // Everytime you enter the loop, enter the dispatch.
                dispatch.enter()
                
                do {
                    // Do something with this document.
                    // You want to perform an additional async task in here,
                    // so fire up another dispatch and repeat these steps.
                    // Consider partitioning these tasks into separate functions
                    // for readability.

                    // At some point in this do block, we must leave the dispatch.
                    dispatch.leave()
                } catch {
                    print(error)
                    
                    // Everytime you leave this iteration, no matter the reason,
                    // even on error, you must leave the dispatch.
                    dispatch.leave()
                    
                    // If there is an error in this iteration, do not return.
                    // Return will return out of the method itself (loadData).
                    // Instead, continue, which will continue the loop.
                    continue
                }
            }
            
            dispatch.notify(queue: .main) {
                // This is the completion handler of the dispatch.
                // Your first round of data is ready, now proceed.
            }
        } else if let error = error {
            // Always log errors to console!!!
            // This should be automatic by now without even having to think about it.
            print(error)
        }
    }
}

मैं यह भी देखा कि भीतर के दूसरे सेट async कार्य के भीतर दूसरी पाश, आप जोड़ रहे हैं, स्नैपशॉट श्रोताओं. कर रहे हैं आप वास्तव में सुनिश्चित करें कि आप ऐसा करना चाहते हैं? नहीं तो आप सिर्फ एक सादे दस्तावेज़ मिलता है?

2021-11-23 16:44:21

आपकी मदद के लिए धन्यवाद! मैं इस को लागू करने में कुछ घंटे के लिए और जांच अगर यह काम करता है के लिए. मैं प्रयोग किया जाता भेजने समूहों और यह एक बार जम अनुप्रयोग है, लेकिन यह किया गया था से थोड़ा अलग अपने सुझाव. सकता है आप प्रदान करते हैं "सही" जिस तरह से यह कर रही है? यहां तक कि अगर इसे बदलने की आवश्यकता है डेटा संरचना है । मैं शामिल कर सकते हैं और अधिक कोड है, इसलिए है कि आप कर सकते हैं एक बेहतर समझ है. एक बार फिर धन्यवाद!
Álvaro Miguel Samagaio

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में