Arafin Russell Arafin Russell - 9 months ago 38
Swift Question

Make friends based on BOOL status, finding difficult comparing the array value , Firebase, Swift

I am making a chat app,I want to make friends only under the condition that, if a userA has friends userB == ture and the same userB has userA == true , I want them to make friend. To make you more clear here is the json format:

user_friends: {
$userA: {
friends: {
$userB: true
}
},
$userB: {
friends: {
$userA: true,
$userC: true
}
},
$userC: : {
friends: {
$userA: true,
$userB: true
}
}
}


As the json above , userA will have userB as friend, userB will have userA & userC as friend and userC will have only userB as friend because userA do not have userC as his friend. Here is my data model, not sure if it is perfect

import Foundation
import SwiftyJSON

struct Friends {
var myFriends:[Bool]!

struct Friend {
let key: String
let is_friend: Bool
init(snap: FIRDataSnapshot) {
self.key = snap.key
self.is_friend = (snap.value != nil)
}
}


And here is the function by which I am trying to fetch the data and compare them, but its not working as I want

func getFriendList() {

if self.user != nil {
_ = self.ref.child("user_friends").child((user?.uid)!).observeSingleEvent(of: .value, with: { snapshot in
for snap in snapshot.children {
for friends in (snap as AnyObject).children {
// cast friend and append to myFriends
print(friends)
let friend = Friend(snap: friends as! FIRDataSnapshot)
self.myFriends.append(friend)
print("my friends are\(self.myFriends.description)")
print("friends count\(self.myFriends.count)")

if (self.myFriends.count > 0) {
for friend in self.myFriends {
_ = self.ref
.child("user_friends")
.child(friend.key)
.child("friends")
//.child((self.user?.uid)!)
.observeSingleEvent(of: .value, with: { snapshot in
print("Desired Snapshot\(snapshot)")
//Now I need to check the condition here

})
}
}
}
}
})


}//FIRAuth ends here

}//getFriendList ends here


And here is my actual database design:friends and the debug result enter image description here I guess I need to take two dictionary and compare their values. Its almost like instagram feature that if someone follows a user and the user follow him back they got message option enabled , message option does not open until they follow each other. Please any kind person come forward and help me. I am in real trouble. Thanks.

Answer Source

You are doing alot of looping and parsing that you dont need to. This is how I would do what you are trying to do:

// A struct for friend nodes on a user account
struct Friend {
    let key: String
    let is_friend: Bool
    init(snap: FIRDataSnapshot) {
        self.key = snap.key
        self.is_friend = snap.value as! Bool
    }
}
// A struct for user account nodes
struct ChatUser {
    var friends = [Friend]()
    let user_ref: FIRDatabaseReference
    let key: String
    init(user_ref: FIRDatabaseReference) {
        self.user_ref = user_ref
        self.key = user_ref.key
    }
}

let currentUser = ChatUser(user_ref: self.user.ref)

func getFriendListForUser(user: ChatUser) {
    _ = user.ref.child("user_friends").observeSingleEvent(of: .value, with: { snapshot in
        for friend in snapshot.children {
            // cast friend and append to myFriends
            let friend = Friend(snap: friend)
            user.friends.append(friend)
        }
    })
}

// validate friend list in firebase for a given chat user
func validatedFriendsForUser(user: ChatUser) {
    for friend in user.friends {
        _ = FIRDatabase.database()
            .reference(withPath: friend.key)
            .child("friends")
            .child(self.currentUser.key)
            .observeSingleEvent(of: .value, with: { snapshot in
                if let status = snapshot as? Bool {
                    friend.is_friend = status
                }
            })
    }

    // Remove friends which are not confirmed in firebase
    self.currentUser.friends = user.friends.filter{ $0 }
}
// call our methods to fetch and filter user friends for current user
self.getFriendListForUser(user: self.currentUser)
self.validatedFriendsForUser(user: self.currentUser)

The validatedFriendsForUser() is not required, but if you want to check to see if user A has user B's key set to true in the database.