1

I have an app where users can like posts and I want to determine if the current user has previously liked a post in an efficient manner. My data currently looks like this:

Post Data

I also store the likes for every user

User Likes

In my current query I am doing this:

if let people = post["peopleWhoLike"] as? [String: AnyObject] {
      if people[(Auth.auth().currentUser?.uid)!] != nil {
           posst.userLiked = true
      }
}

However, I believe this requires me to download all of the post's likes which isn't very efficient, so I tried this:

 if (post["peopleWhoLike\(Auth.auth().currentUser!.uid)"] as? [String: AnyObject]) != nil {
     posst.userLiked = true
 }

The second method doesn't seem to be working correctly. Is there a better way to do this?

Here is my initial query as well:

pagingReference.child("posts").queryLimited(toLast: 5).observeSingleEvent(of: .value, with: { snap in
        for child in snap.children {
            let child = child as? DataSnapshot
            if let post = child?.value as? [String: AnyObject] {
                let posst = Post()
                if let author = post["author"] as? String, let pathToImage = post["pathToImage"] as? String, let postID = post["postID"] as? String, let postDescription = post["postDescription"] as? String, let timestamp = post["timestamp"] as? Double, let category = post["category"] as? String, let table = post["group"] as? String, let userID = post["userID"] as? String, let numberOfComments = post["numberOfComments"] as? Int, let region = post["region"] as? String, let numLikes = post["likes"] as? Int {
DoesData
  • 6,594
  • 3
  • 39
  • 62
  • This is called many to many relationships, check this out: https://www.youtube.com/watch?v=HjlQH3RsGcU in the middle of the video Frank will say something about it. https://stackoverflow.com/questions/41527058/many-to-many-relationship-in-firebase is maybe something you can use. I think you should denormalise your database to query quicker. Yes you get duplicate data this way. – J. Doe Sep 01 '17 at 22:56
  • The data is already denormalized since the like is stored in posts and userActivity... – DoesData Sep 01 '17 at 23:04

1 Answers1

0

Solved it:

In the tableView I just query for the liked value directly and then determine what button to display.

static func userLiked(postID: String, cell: BetterPostCell, indexPath: IndexPath) {
        // need to cache these results so we don't query more than once
        if newsfeedPosts[indexPath.row].userLiked == false {
            if let uid = Auth.auth().currentUser?.uid {
                likeRef.child("userActivity").child(uid).child("likes").child(postID).queryOrderedByKey().observeSingleEvent(of: .value, with: { snap in
                    if snap.exists() {
                        newsfeedPosts[indexPath.row].userLiked = true
                        cell.helpfulButton.isHidden = true
                        cell.notHelpfulButton.isHidden = false
                    }
                })
                likeRef.removeAllObservers()
            }
        }
    }

Called in my TableView:

DatabaseFunctions.userLiked(postID: newsfeedPosts[indexPath.row].postID, cell: cell, indexPath: indexPath)
DoesData
  • 6,594
  • 3
  • 39
  • 62