简体   繁体   中英

Store values from multiple loops into an array with Firebase. Swift

I've been trying to figure out how to get an array of users data and compare it with a list of other users array to see if it matches them. I've looked at the answer here which demonstrates that I should structure my data so that it is denormalised and therefore have duplicates. This approach works but I am now struggling to store these array into one array which can be used to later on.

Here is an example of my data structure:

{
  “skills”: [
    {
      "name": "Walking"
    },
    {
      "name": "Running",
      "usersWithSkill": [
        “user1”: true,
        “user2”: true,
        “user3”: true
      ]
    },
    {
      "name": "Swimming",
      "usersWithSkill": [
        “user3”: true
      ]
    },
    {
      "name": "Dancing",
      "usersWithSkill": [
        “user1”: true,
        “user3”: true
      ]
    }
  ],
  "users": {
    "user1": {
      "firstName": "Amelia",
      "skillsList": [
        "1": true,
        "3": true
      ]
    },
    "user2": {
      "firstName": "Elena",
      "skillsList": [
        "1": true,
      ]
    },
    "user3": {
      "firstName": "John",
      "skillsList": [
        "1": true,
        "2": true,
        "3": true
      ]
    },
    “user4”: {
      "firstName": "Jack",
      "interestsList": [
        "1": true,
        "3": true
      ]
   }
  }
}

I am able to query the interests which Jack has. However the loop happens twice and therefore I'm struggling to append an array that stores the values of the users that Jack is looking for.

This is how I query the skills:

var newArray = [String]()

func fetchSkillKeys() {

    // Loop through the array of interest keys
    for key in self.arrayOfInterestKeys {
        let interestRef = Database.database().reference(withPath: "skills/\(key)/usersSkill")
        interestRef.observeSingleEvent(of: DataEventType.value, with: { (snapshot) in
            for child in snapshot.children {
                guard let snapshot = child as? DataSnapshot else { continue }
                self.newArray.append(snapshot.key)
            }
            print(self.newArray)
        })
    }
}

This is how my array when printed on the console:

[]
["0", "1", "2"]
["0", "1", "2", "0", "1", "2"]
["0", "1", "2", "0", "1", "2", "0", "1"]

When I'm expecting something like:

["0", "1", "2", "0", "1"]

Update

Responding to the comment below, the arrayOfInterestKeys is keys taken from the interestsList which I use as a reference when querying the skills I want to observe, here is how I fetch them:

var arrayOfInterestKeys = [String]()

func fetchUserInterests() {

    guard let uid = Auth.auth().currentUser?.uid else { return }
    // Go to users interest list
    let databaseRef = Database.database().reference(withPath: "users/\(uid)/interestsList")

    // Observe the values
    databaseRef.observeSingleEvent(of: DataEventType.value, with: { (snapshot) in

        // Loop through the interests list
        for child in snapshot.children {
            guard let snapshot = child as? DataSnapshot else { continue }
            // Populate an empty array
            self.arrayOfInterestKeys.append(snapshot.key)
        }
   })
}

You have:

for child in snapshot.children {
    guard let snapshot = child as? DataSnapshot else { continue }
    self.newArray.append(snapshot.key)
}
print(self.newArray)

Try:

for child in snapshot.children {
    let child = child as? DataSnapshot
    if let key = child?.key {
        // Make sure the key is not in the array
        if self.newArray.index(of: key) == nil {
            self.newArray.append(key)                                
        }
    }
}

Also I'd like to know how / where you are calling fetchSkillKeys()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM