2

我已经在这个问题上待了三天多,我进行了研究,并遇到了与我的问题相关的其他类似问题,但这些修复无法解决我的问题,因此我问这个问题的原因。

我在 firebase 中有一个 users、posts 和 users-posts 节点,如下所示。我想在节点上运行一个查询,这样如果两个用户是朋友,他们就可以看到彼此的帖子。但是如果他们不是朋友,他们就看不到彼此的帖子

Users
 123840ajldkjfas0d9
   username: Joe
   friend
     78983049802930laks: true 
     78983049802930laks: true

 4563049802930laks
   username: Ken
   friend
     123840ajldkjfas0d9: true

 78983049802930laks
   username: Pean
   friend
      123840ajldkjfas0d9: true 

posts
 876f92fh02hfj02930239
   post: This is cool
   whoposted: 123840ajldkjfas0d9

 39fh938hqw9320923308
   post: I love pizza
   whoposted: 78983049802930laks

 users-posts
  123840ajldkjfas0d9
   876f92fh02hfj02930239: true

  78983049802930laks
   39fh938hqw9320923308: true

这是我目前的查询,它显示所有用户的所有帖子,无论他们是否是朋友。请我需要帮助。

    DataService.ds.REF_USERS.observe(.value, with: { (userSnapshot) in
    if let snapshot = userSnapshot.children.allObjects as?   
    [FIRDataSnapshot]{
            for userSnap in snapshot{
                print("snapshot.key: \(userSnap.key)")
                let userKey = userSnap.key
                if var userDict = userSnap.value as? Dictionary<String, 
    AnyObject>{

    let postUserPicUrl = userDict["profileImgUrl"] as? String

    if let firstName = userDict["firstName"] as? String{
                        ("firstName: \(firstName)")

    DataService.ds.REF_POST.observeSingleEvent(of: .value, with: { 
    (postSnapshot) in
    if let postSnapshot = postSnapshot.children.allObjects as? 
    [FIRDataSnapshot]{
    for postSnap in postSnapshot{
    if var postDict = postSnap.value as? Dictionary<String, AnyObject>{
    if let refPostUserKey = postDict["user"] as? String{
    if userKey == refPostUserKey{ 

    DataService.ds.REF_BLOCK_USER.observeSingleEvent(of: .value, with: {
    (blockUserSnapshot) in
    if let blockUserSnapshot = blockUserSnapshot.children.allObjects as?
    [FIRDataSnapshot] {
    for blockUserSnap in blockUserSnapshot{
    if var blockUserDict = blockUserSnap.value as? Dictionary<String, 
    AnyObject> {
    if let      user = blockUserDict["user"] as? String{                          
    if firstName != user {                                                                                                                                                               
    postDict["postUserPicUrl"] = postUserPicUrl  as AnyObject?;                                                    
        let postKey = postSnap.key
        let post = Post(postKey: postKey, postData: postDict)

        self.posts.append(post)

                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                             self.tableView.reloadData()
                                                })




                                            }
                                        }
                                    }
                                }
                            }
                          self.tableView.reloadData()
                        })
                    }
                 }
              }
          }
         self.tableView.reloadData()
      })
   }
4

1 回答 1

1

我的意思是没有不尊重的意思,但是您没有很好地利用这些查询,每个查询都嵌套在另一个查询中。此外,请确保更新所有查询。Post 查询使用旧格式,而您的用户查询是最新的。

您应该创建 3 个字典来保存每个节点用户、帖子、用户帖子的数据以及一个 var 来保存当前用户字符串和一个字典来包含帖子数据:

var users = [String:Any]()
var posts = [String:Any]()
var usersposts = [String:Any]()
var currentUserKey:String!
var visibleposts = [String:Any]()

然后有三个单独的查询来获取数据。目前,您似乎没有查询任何特定用户,所以我也会这样做:

func getUserData(){
    DataService.ds.REF_USERS.observe(.childAdded, with: {snapshot in 
        let key = snapshot.key
        let data = snapshot.value as? [String:Any] ?? [:]
        self.users[key] = data
    })
}
func getPostsData(){
    DataService.ds.REF_POST.observe(.childAdded, with: {snapshot in 
        let key = snapshot.key
        let data = snapshot.value as? [String:Any] ?? [:]
        self.posts[key] = data
        self.refreshPosts()
    })
}
func getUsersPostsData(){
    DataService.ds.REF_BLOCK_USERS.observe(.childAdded, with:{snapshot in // I am guessing you have the users posts here?? there doesn't seem to be sample data for blocked users in your OP
        let key = snapshot.key
        let data = snapshot.value as? [String:Any] ?? [:]
        self.usersposts[key] = data
        self.refreshPosts()
    })
}

现在在视图中触发这些查询之前获取当前用户确实加载然后调用每个查询。

override func viewDidLoad(){
    self.currentUserKey = (FIRAuth.auth()?.currentUser?.uid)! 
    /* you may want to do some error handling here to ensure the user 
    is actually signed in, for now this will get the key if 
    they are signed in */
    self.getUserData()
    self.getPostsData()
    self.getUsersPostsData()

    // data will be refreshed anytime a child is added
}
func refreshPosts(){
    self.validposts = [:]
    let validUsers = [String]() // this will hold the valid keys to get posts
    validUsers.append(self.currentUserKey)
    let currentUserData = users[self.currentUserKey] // filter the current user data to get the friends
    // get friends keys
    let friendsData = currentUserData["friends"] as? [String:Any] ?? [:]
    for key in friendsData.keys {
        // add friends posts to the validposts data
        validUsers.append(key)
    }
    // get current users posts:
    for (key,value) in self.posts {
        let postData = value as? [String:Any] ?? [:]
        let whoposted = postData["whoposted"] as? String ?? ""
        if validUsers.contains(whoposted){
            self.validposts[key] = postData
        }
    }
    // access the self.validposts data in your UI however you have it setup

    // The child added queries above will continue to fire off and refresh 
    // your data when new posts are added.

    // I am still not clear what the usersposts data is for so it is omitted here.
}
于 2017-02-18T07:08:34.340 回答