Firebase Swift查询和客户端扇出

时间:2017-02-17 18:59:30

标签: swift firebase firebase-realtime-database firebase-queue

我已经在这个问题上工作了三天以上,我有研究,并且遇到了与我的问题有关的其他类似问题,但是那些修复无法解决我的问题,因此问我这个问题。

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

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()
      })
   }

1 个答案:

答案 0 :(得分: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.
}