我现在可以按时间对帖子和用户进行排序。
我的数据结构如下:
posts
-postId
imageRatio:
imageUrl:
postText:
postTime:
uId:
users
-UserId
email:
profileImageURL:
radius:
uid:
username:
username_lowercase:
更新
现在,我创建了一个新类,其中包含用户和帖子的所有数据:
class UserPostModel {
var post: PostModel?
var user: UserModel?
init(post: PostModel, user: UserModel) {
self.post = post
self.user = user
}
}
我的post数组声明:
var postArray = [UserPostModel]()
在这里,我将数据加载到新类中:
self.observeRadius(completion: { (radius) in
let currentRadius = radius
// Üperprüfe, welche Posts im Umkreis erstellt wurden
let circleQuery = geoRef.query(at: location!, withRadius: Double(currentRadius)!)
circleQuery.observe(.keyEntered, with: { (postIds, location) in
self.observePost(withPostId: postIds, completion: { (posts) in
guard let userUid = posts.uid else { return }
self.observeUser(uid: userUid, completion: { (users) in
let postArray = UserPostModel(post: posts, user: users)
self.postArray.append(postArray)
print(postArray.post!.postText!, postArray.user!.username!)
self.postArray.sort(by: {$0.post!.secondsFrom1970! > $1.post!.secondsFrom1970!})
})
})
在这里,我将数据加载到表视图单元格中:
extension DiscoveryViewController: UITableViewDataSource {
// wie viele Zellen
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(postArray.count)
return postArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DiscoveryCollectionViewCell", for: indexPath) as! DiscoveryCollectionViewCell
cell.user = postArray[indexPath.row]
cell.post = postArray[indexPath.row]
//cell.delegate = self
return cell
}
}
提前谢谢你的帮助!
最佳答案
问题中有很多代码,有时候,更简单更好。因此,让我们获取一个post类,加载post s,获取相关的用户名并将其存储在一个数组中。完成后,按时间倒序排序并打印文章。
保存post数据和用户名的类
class PostClass {
var post = ""
var timestamp: Int! //using an int for simplicity in this answer
var user_name = ""
init(aPost: String, aUserName: String, aTimestamp: Int) {
self.post = aPost
self.user_name = aUserName
self.timestamp = aTimestamp
}
}
注意,如果我们想同时拥有post数据和用户数据,我们可以这样做
class PostUserClass {
var post: PostClass()
var user: UserClass()
}
但我们对这个答案保持简单。
然后一个数组来存储posts
var postArray = [PostClass]()
最后是要在所有文章中加载的代码,获取相关的用户名(或完整示例中的用户对象)。
let postsRef = self.ref.child("posts")
let usersRef = self.ref.child("users")
postsRef.observeSingleEvent(of: .value, with: { snapshot in
let lastSnapIndex = snapshot.childrenCount
var index = 0
for child in snapshot.children {
let childSnap = child as! DataSnapshot
let uid = childSnap.childSnapshot(forPath: "uid").value as! String
let post = childSnap.childSnapshot(forPath: "post").value as! String
let timestamp = childSnap.childSnapshot(forPath: "timestamp").value as! Int
let thisUserRef = usersRef.child(uid)
thisUserRef.observeSingleEvent(of: .value, with: { userSnap in
index += 1
//for simplicity, I am grabbing only the user name from the user
// data. You could just as easily create a user object and
// populate it with user data and store that in PostClass
// that would tie a user to a post as in the PostUserClass shown above
let userName = userSnap.childSnapshot(forPath: "Name").value as! String
let aPost = PostClass(aPost: post, aUserName: userName, aTimestamp: timestamp)
self.postArray.append(aPost) //or use self.postUserArray to store
// PostUserClass objects in an array.
if index == lastSnapIndex {
self.sortArrayAndDisplay() //or reload your tableView
}
})
}
})
还有一个小函数,用来排序和打印到控制台
func sortArrayAndDisplay() {
self.postArray.sort(by: {$0.timestamp > $1.timestamp})
for post in postArray {
print(post.user_name, post.post, post.timestamp)
}
}
注意,firebase是异步的,所以在排序/打印之前,我们需要知道已经完成了所有数据的加载。这是通过LastSnapIndex和Index处理的。索引只在每个用户加载后递增,当所有帖子和用户都加载后,我们会在数据完成时进行排序和打印。
这个例子避免了可能导致问题的混乱回调和完成处理程序——这段代码是可疑的,可能应该避免,因为firebase是异步的;sort函数将在所有用户加载之前被调用。
UserApi.shared.observeUserToPost(uid: userUid) { (user) in
self.postUser.append(user)
}
self.postUser.sort(by: {$0.postDate! > $1.postDate!})
*请添加错误检查。
关于swift - 如何在Firebase中对数据排序?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53570841/