Learn2Code
Learn2Code

Reputation: 2280

Swift Firebase read from multiple nodes

I am trying to solve the issue where I want to populate a collection view cell with the match information that is across two nodes and needs to read multiple times in the 'Player' node.

Here is my Firebase Database Structure

{
    Players:
        LpWgezRkC6EWS0sjXEWxhFl2: {
            userName: 'John Doe'
            teamId: '234'
            teamName: 'Revenge'
            teamLogo: 'star.png'
            etc...
        },
        RfskjEWSkdsjkjdskjsd12fg: {
            userName: 'Jane Doe'
            teamId: '987'
            teamName: 'Frills'
            teamLogo: 'jag.png'
            etc...
        }
    },
    Matches: 
        12345: {
            User1: 'LpWgezRkC6EWS0sjXEWxhFl2'
            User2: 'RfskjEWSkdsjkjdskjsd12fg'             
            date: '11/10/17'
            WeekId: 19
            etc...
        }
    }
}

As you can see the 'Matches' node holds the 'Players' info so in the collection view I am looking to display the player1 vs player2 information.

The code I have so far is this:

self.ref.queryOrdered(byChild: "WeekId").queryEqual(toValue: 19).observe(.value, with: { snapshot in 

    var items: [Match] = []

    for item in snapshot.children {

        let snapshotValue = (item as! DataSnapshot).value as? NSDictionary

        let pId1 = snapshotValue!["User1"] as! NSString
        let pId2 = snapshotValue!["User2"] as! NSString

        let match = Match(snapshot: item as! DataSnapshot)

        items.append(match)

    }

    self.matches = items

    self.collectionView?.reloadData()
}

I am not really sure how to do the second lookup into the 'Players' node (which I would need 2) since it needs to lookup both players info, all without racing past the let match = Match(snapshot: item as! DataSnapshot) function, else it will fail?

Can anyone help please!

Upvotes: 1

Views: 482

Answers (1)

Rozario Rapheal
Rozario Rapheal

Reputation: 278

You can add

self.ref.queryOrdered(byChild: "WeekId").queryEqual(toValue: 19).observe(.value, with: { snapshot in

        var items: [Match] = []

        for item in snapshot.children {

            let snapshotValue = (item as! DataSnapshot).value as? NSDictionary

            let pId1 = snapshotValue!["User1"] as! NSString
            let pId2 = snapshotValue!["User2"] as! NSString

            fetchUserProfile(withUID: pId1, completion: { (userDict1) in
                // Here you get the userDict 1
                self.fetchUserProfile(withUID: pId2, completion: { (userDict2) in
                    //Here you get the user dict 2
                    let match = Match(snapshot: item as! DataSnapshot)
                    items.append(match)
                })
            })
        }

        self.matches = items

        self.collectionView?.reloadData()
    })

// Fetch user profile with completion

func fetchUserProfile(withUID uid: String, completion: @escaping (_ profileDict: [String: Any]) -> Void) {
    // New code
    Database.database().reference().child(uid).observe(.value, with: { snapshot in
        // Here you can get the snapshot of user1
        guard let snapDict = snapshot.value as? [String: Any] else {return}
        completion(snapDict)
    })
}

I don't think this the right way to solve this. I suggest you to capture the pIDs for all users and save it in a array of UserProfiles. When needed you can fetch the user profiles from that array. Hope It helps.

Upvotes: 1

Related Questions