2017-02-17 98 views
2

我已经在这个问题上三天了,我有研究,并且遇到了与我的问题有关的其他类似问题,但这些修复无法解决我的问题,因此我问的原因这个问题。Firebase Swift查询和客户端扇出

我在firebase中有一个用户,帖子和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() 
     }) 
    } 
+0

我将面临正是这种情况很快就在我的项目,希望你会得到一个答案很快 –

+0

你的代码是一个烂摊子,这是非常困难的阅读 - 这使得它非常困难提供帮助。请修正格式,特别是嵌套函数的缩进。 – Pierce

回答

1

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

应该创建3个字典来保存每个节点的用户,文章,用户,帖子中的数据,以及一个变种,以保持当前用户的字符串,并包含POST数据字典:

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. 
} 
+0

@mathew非常感谢您的反馈。我似乎正在取得进展。我目前遇到的问题是打印时显示空白。你能给些建议么? –

+0

你用来打印数据的代码是什么?另外,尝试打印快照以查看是否有任何数据。 – matthew

+0

@mathew这是打印出来,我能够填充我的用户界面。但数据正在被复制。最初,我认为这是表格视图单元格的问题。但经过检查,我重新指出,当我打印usersposts和用户时,其中的数据被复制。你能否建议如何摆脱重复的数据 –