เป็ Firestore กับการค้นหาข้างในแผนที่ฟังก์ชันในรี

0

คำถาม

ฉันเป็นคนใหม่เพื่อ SwiftUI และ Firebase และฉันกำลังพยายามสร้างแรกของแอพ ฉันเป็นเกมจัดเก็บเอกสารใน Firestore และหนึ่งของช่องข้อมูลคือตารางคู่ลำดับที่บรรจุของผู้ใช้บัตรของเครื่องเล่นอย่างที่คุณสามารถมองเห็นในภาพได้ที่นี่

เกมข้อมูลของโครงสร้าง

อย่างที่บอกฉันกำลังพยายามแสดงรายการของเกมส์ของให้ผู้ใช้และมีทั้งหมดเครื่องเล่นอยู่ในรายการในแต่ละคนของเซลล์(คำสั่งสำคัญมาก).

เพื่อสร้างรายการของเกมส์อยู่ในส่วนติดต่อผู้ใช้ฉันสร้าง GameCellListView และ GameCellViewModel. ที่ GameCellViewModel ควรจะโหลดทั้งสองคนเกมส์และอาเรย์ของผู้ใช้นั้นธ์ที่เครื่องเล่นของเกม แต่ฉันไม่สามารถโหลดข้อมูลผู้ใช้จะเป็นอาเรย์. ฉันต้องไปผ่านเครื่องเล่นอาเรย์กับการค้นหาฐานข้อมูลสำหรับแต่ละตัวและเพิ่มเข้าไปเป็นของผู้ใช้อาเรย์;งั้นฉันควรจะกลับไปนี่ของผู้ใช้อาเรย์. ตั้งแต่ฉันกำลังใช้สำหรับวงฉันไม่สามารถกำหนดค่าไปที่อาเรย์แล้วจากนั้นก็แลกเปลี่ยนมัน ฉันพยายามใช้แผนที่()แต่ฉันไม่สามารถแสดงการสืบค้นข้างในของมัน เป้าหมายคือรถโหลดว่า"เรื่องทั้งหมด"variance กับ struct นั้นอย่างเราได้รับคำขู่แบบนี้เป็นเกมและเครื่องเล่นของมัน GamePlayers(players: [User], game: Game)

มันควรจะดูบางอย่างเหมือนรหัส snippet ด้านล่างนี้แต่งที่ผู้ใช้อาเรย์เสมอมาว่างเปล่า ฟังก์ชันนี้วิ่งอยู่ 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

มีหลายของย้ายบ้านส่วนในของคุณรหัสและต้องแยกคะแนนของความล้มเหลวคงต้องการเห็นเพิ่มเติมรหัสงั้นเป็นแค่ระมัดระวังเรื่องนั้นเป็นอย่า upfront. นั่นบอกว่าถ้าคุณค่อนข้างใหม่ที่จะต้อง Firestore หรือรีบแล้วฉันคงแนะนำว่าพวกคุณก่อนจะจัดการกับฟังก์ชันนี้ใช้พื้นฐานรูปแบบการสั่งงาน. เมื่อคุณพอใจกับที่เกิดขึ้นและ outs ของ async การวนรอบแล้วฉันจะแนะนำให้ refactoring รหัสโดยใช้อีกขั้นสูงรูปแบบการสั่งงานเหมือนคุณต้องอยู่ที่นี่

ของคุณฟังก์ชันต้องการแสดง async ทำงานภายในแต่ละเรื่องทำซ้ำ(ของเอกสาร). คุณต้องทำอย่างนี้สองครั้ง async ทำงานในวงในเรื่อยๆ ต้องแน่ใจว่านี่คือสิ่งที่คุณต้องการจะทำอย่างก่อนที่กำลังเพราะมันอาจจะเป็นเครื่องมือทำความสะอาดวิธีซึ่งอาจจะรวมเป็นมากกว่ามีประสิทธิภาพเพียงพอ smooth scrolling 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 งานภายในสองวงคุณเพิ่มภาพที่จับได้ปัจจุบันโดยเลือ listeners. คุณแน่ใจหรือว่าคุณอยากทำอย่างนี้? คุณไม่ต้องการเอกสารธรรมดาได้?

2021-11-23 16:44:21

ขอบคุณสำหรับการช่วยด้วย! ฉันจะทำด้วยอะไรซักอย่างนี้ในอีกไม่กี่ชั่วโมงและตรวจสอบว่ามันทำงานสำหรับของฉัน. ฉันเคยแยกชิ้นส่วนกลุ่มครั้งนึงและมันแข็งแอพฯ,แต่มันเป็นข้อแตกต่างเพียงเล็กน้ออกจากคุณแนะนำ คุณช่วยให้คน"ที่ถูกต้อง"ทางของการทำเรื่องนี้? ถึงแม้ว่ามันต้องการเปลี่ยนข้อมูลของโครงสร้างของ. ฉันสามารถรวมมากกว่ารหัสดังนั้นคุณสามารถมีความเข้าใจ ขอบคุณอีกครั้ง!
Álvaro Miguel Samagaio

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่