2017-02-17 96 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和用戶時,其中的數據被複制。你能否建議如何擺脫重複的數據 –