Daniel Dramond Daniel Dramond - 4 years ago 94
Swift Question

Fetch users data only if it matches current users data

I have a tableView that fetches all of the users in my Firebase Database. The tableView cell simply displays the users name, email and profile image. The problem is that I also want the user to have an attributes key stored under their UID in the users node that will hold an array of attributes that they chose in the app (the attributes in this example will be ["food", "drink", "sports"]) and I want to only display the users that have 3 or more of the same attributes as the current signed in user.

The first issue is that I don't know how to go about adding an array of attributes to my firebase database under my UID as it saves as an attributes node with a list from Index 0 to Index 2 (3 keys 0,1,2) with the strings "food", "drink", "sports". I also don't know if this is the best way to go about this. Any help will be appreciated.

The second problem is that I don't know how to fetch a new user and add it to my tableView IF ONLY that user has the same attributes as the current user.
Here is my current code that fetches ALL users, without any filtering:

func fetchUser() {
FIRDatabase.database().reference().child("users").observe(.childAdded, with: { (snapshot) in

if let dictionary = snapshot.value as? [String: AnyObject] {
let user = User()

user.setValuesForKeys(dictionary)

self.users.append(user)



DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}

}, withCancel: nil)
}

class User: NSObject {

var name: String?
var email: String?
var numberId: String?

var attributes: String?

var password: String?
var profileImageUrl: String?
}

Jay Jay
Answer Source

First. Don't use arrays. They are extremely situational and there are usually other, better ways to store data.

Answer to first question:

Given a Firebase structure where you want to store the user data and some attributes, here's one structure that will do it

users
  uid_0
    name: "Frank"
    attribs
      fav_food: "Pizza"
      fav_car: "Camaro"

and to read the above node

usersRef.observe(.value, with: { snapshot in

    for child in (snapshot?.children)! {
        let snap = child as! FDataSnapshot 
        let dict = snap.value as! [String: AnyObject] 

        let name = dict["name"] //it's Frank

        let attribs = dict["attribs"] as! [String: AnyObject]
        let food = attribs["fav_food"] //pizza
        let car = attribs["fav_car"] //camaro
    }
}

Answer to second question:

The second problem is that I don't know how to fetch a new user and add it to my tableView IF ONLY that user has the same attributes as the current user. Here is my current code that fetches ALL users, without any filtering:

So what you are asking is how to find other users that have the same attribs as the current user.

Firebase doesn't have the ability to perform comparisons upon multiple children (i.e. there is no: where food == pizza and car = Camaro).

One option is to store the attribs as a string

pizza_Camaro

then you can easily check to see if the attribs' strings are equal.

Another option is a recursive query. Here's the idea at a 10k foot level

query for all users where fav_food is pizza
   query from that set of users where fav_car is Camaro
      query from that set of users where....

You get the idea. It's not super efficient but for small datasets it can work.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download