Swift 按上次喜欢的时间和最近两次喜欢的时间组织Firebase

Swift 按上次喜欢的时间和最近两次喜欢的时间组织Firebase,swift,firebase-realtime-database,Swift,Firebase Realtime Database,我有一个社交应用程序,我想向用户显示最近喜欢的帖子,以及最近喜欢这篇帖子的两个人。显示类似“用户A和用户B喜欢和31个其他人喜欢您的帖子”的内容,其中31个其他人喜欢的帖子比用户A和用户B最近的帖子要少,并且此特定帖子是用户最喜欢的帖子 鉴于这些要求,我正试图找出构建firebase的最佳方法。我想我会将与帖子相关的lastLiked时间戳存储在likeActivity中,然后将时间戳用作喜欢帖子的用户的键(见下文) 考虑到我上面的要求,这是最好的方式吗?如果是这样,我在为我的iOS应用程序检索

我有一个社交应用程序,我想向用户显示最近喜欢的帖子,以及最近喜欢这篇帖子的两个人。显示类似“用户A和用户B喜欢和31个其他人喜欢您的帖子”的内容,其中31个其他人喜欢的帖子比用户A和用户B最近的帖子要少,并且此特定帖子是用户最喜欢的帖子

鉴于这些要求,我正试图找出构建firebase的最佳方法。我想我会将与帖子相关的
lastLiked
时间戳存储在
likeActivity
中,然后将时间戳用作喜欢帖子的用户的键(见下文)

考虑到我上面的要求,这是最好的方式吗?如果是这样,我在为我的iOS应用程序检索这些时会遇到很多麻烦,因为当我调用
snapshot.children.allObjects
时,我不仅会得到
likes
时间戳,还会得到
lastLiked
时间戳。如何重新使用
observeActivity
函数来提取按
lastLike
排序的数据,然后按
时间戳排序。我阅读了有关在Firebase中订购数据的文档,但不确定如何将其应用到我的环境中

func observeActivity () {
    guard let uid = Auth.auth().currentUser?.uid else {
        return
    }

    let newActivity = DataService.ds.REF_LIKE_ACTIVITY.child("\(uid)")

    newActivity.observe(.value, with: {(snapshot) in

        self.posts = []

        if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {

            for snap in snapshot{

                let postKey = snap.key
                //self.posts.append(snap.key)

                let userLikeData = newActivity.child("\(snap.key)").child("userLikes")

                userLikeData.observe(.value, with:  {(snapshot) in

                    if let newSnap =  snapshot.children.allObjects as? [DataSnapshot] {

                        for valueSnap in newSnap {
                            //Users who have liked the post
                            print("SNAPTIVITY \(valueSnap.value!)")
                            let userId = valueSnap.value!
                            //self.userArray.append("\(userId)")

                            if self.activityDict["\(postKey)"] != nil {
                                self.activityDict["\(postKey)"]!.append("\(userId)")
                            } else {
                                self.activityDict["\(postKey)"] = ["\(userId)"]
                            }

                        }
                        let postData = DataService.ds.REF_POSTS.child(postKey)
                        postData.observe(.value, with: { (snapshot) in
                            if let postDict = snapshot.value as? Dictionary<String, AnyObject> {
                                let key = snapshot.key
                                let post = Post(postKey: key, postData: postDict, isLiked: 0)
                                self.posts.append(post)
                            }


                            //self.feedTableView.reloadData()
                            self.activityTableView.reloadData()
                        })
                    }

                })
            }
        }

    })


}
func可观测性(){
guard let uid=Auth.Auth().currentUser?.uid else{
返回
}
让newActivity=DataService.ds.REF与ACTIVITY.child类似(“\(uid)”)
newActivity.observe(.value),其中:{(快照)位于
self.posts=[]
如果让snapshot=snapshot.children.allObjects为?[DataSnapshot]{
用于管理单元快照{
让postKey=snap.key
//self.posts.append(snap.key)
让userLikeData=newActivity.child(\(snap.key)”).child(“userLikes”)
userLikeData.observe(.value,其中:{(快照)位于
如果让newSnap=snapshot.children.allObjects为?[DataSnapshot]{
用于新闻快照中的值管理单元{
//喜欢该帖子的用户
打印(“SNAPTIVITY\(valueSnap.value!))
让userId=valueSnap.value!
//self.userArray.append(“\(userId)”)
如果self.activityDict[“\(postKey)”!=nil{
self.activityDict[“\(postKey)”!.append(“\(userId)”)
}否则{
self.activityDict[“\(postKey)”]=[“\(userId)”]
}
}
让postData=DataService.ds.REF\u POSTS.child(postKey)
postData.observe(.value,其中:{(快照)位于
如果让postDict=snapshot.value作为字典{
让key=snapshot.key
让post=post(postKey:key,postData:postDict,isLiked:0)
self.posts.append(post)
}
//self.feedTableView.reloadData()
self.activityTableView.reloadData()
})
}
})
}
}
})
}

在大多数社交网络应用程序中,每个用户最多只能喜欢一篇文章。您当前对这些类的数据模型是:

"userLikes" : {
  "1582337525616" : "BmvRlWWuGRWApqFvtT8mXQlDWzz2",
  "1582337525620" : "Ff0CxZhQzYVHuqbnsiOKwRAB01D2"
}
此模型允许单个用户多次喜欢同一帖子。虽然可以防止这种情况在应用程序代码中发生,但在安全规则中无法强制执行

因此,在Firebase&Firestore中建模数据时,一条非常难的规则是:如果某些内容必须是唯一的,则必须是子节点/文档的键

基于此,我将这个片段建模为:

"userLikes" : {
  "BmvRlWWuGRWApqFvtT8mXQlDWzz2": 1582337525616,
  "Ff0CxZhQzYVHuqbnsiOKwRAB01D2": 1582337525620
}
您将注意到,这现在还允许您将时间戳存储为一个数字,这可以防止所有可能的排序问题


我假设您的数据结构是:

likeActivity
  $uid
    $postId: ...
由于您正在检索当前用户的帖子列表,因此只能根据每个帖子下固定路径上的值对结果帖子进行排序

因此,您可以在帖子的
lastLiked
上对帖子进行排序,但无法确定该帖子下的
userLikes
的返回顺序。您必须在应用程序代码中对这些结果重新排序,以确定最新的like(r)

likeActivity
  $uid
    $postId: ...