我目前正在构建一个应用程序,其中有一个主要供稿,该供稿显示了您关注的所有人的帖子。当您关注某人时,他们的所有帖子都会添加到您的“供稿”中。在我的Firebase数据库中,有一个供稿节点,其中包含对您关注的每个人的帖子的引用,包括当前用户自己创建的帖子。我有一个函数“ loadPosts()”,该函数获取对每个用户帖子的引用,获取帖子的数据,然后将该数据添加到数组中,然后显示在collectionView中。
我正在尝试使用基于“ creationDate”的查询从firebase对该数据进行分页,并且当我不关注任何人时,我的代码可以正常工作,但是一旦我关注具有不同userId的人,主供稿就开始复制帖子而不正确地订购它们。这是我正在获取的数据的快照:
简单来说,数据结构为:
Sub company_statement()
Dim lr As Long
Dim ws As Worksheet
Dim vcol, i As Integer
Dim icol As Long
Dim myarr As Variant
Dim title As String
Dim titlerow As Integer
vcol = 6
Set ws = Sheets("Company Statement Hanley")
lr = ws.Cells(ws.Rows.Count, vcol).End(xlUp).Row
title = "A1:AE1"
titlerow = ws.Range(title).Cells(1).Row
icol = ws.Columns.Count
ws.Cells(1, icol) = "Unique"
For i = 2 To lr
On Error Resume Next
If ws.Cells(i, vcol) <> "" And _
Application.WorksheetFunction.Match(ws.Cells(i, vcol), ws.Columns(icol), 0) = 0 Then
ws.Cells(ws.Rows.Count, icol).End(xlUp).Offset(1) = ws.Cells(i, vcol)
End If
Next
myarr = Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
ws.Columns(icol).Clear
For i = 2 To UBound(myarr)
ws.Range(title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = myarr(i) & ""
Else
Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
End If
ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
Sheets(myarr(i) & "").Columns.AutoFit
Next
ws.AutoFilterMode = False
ws.Activate
End Sub
“ post_uid”属性是创建帖子的用户的uid,而“ creationDate”属性是创建帖子的时间。下面是loadPosts()函数:
"feed": {
"uid": {
"post1Key": {
"creationDate",
"post_uid"
},
"post2Key": {
"creationDate",
"post_uid"
},
}
}
然后有一个名为show(forKey,uid)的函数,该函数从在loadPosts()中获取的引用返回Post对象:
static func loadPosts(posts: [Postt], isFinishedPaging: Bool, completion: @escaping ([Postt], Bool) -> Void) {
guard let uid = Auth.auth().currentUser?.uid else {return}
var pagingTemp = isFinishedPaging
let ref = Database.database().reference().child("feed").child(uid)
var query = ref.queryLimited(toLast: 4).queryOrdered(byChild: "creationDate")
if posts.count > 0 {
let value = posts.last?.creationDate.timeIntervalSince1970
query = query.queryEnding(atValue: value)
}
query.observeSingleEvent(of: .value, with: { (snapshot) in
var completedPosts = [Postt]()
guard var allObjects = snapshot.children.allObjects as? [DataSnapshot] else {return}
allObjects.reverse()
if allObjects.count == 0 || allObjects.count == 1 {
pagingTemp = true
}
if posts.count > 0 && allObjects.count > 0 {
allObjects.removeFirst()
}
let dispatchGroup = DispatchGroup()
for postData in allObjects {
guard let postDict = postData.value as? [String : Any],
let postId = postDict["post_uid"] as? String
else { return }
dispatchGroup.enter()
PostClient.show(forKey: postData.key, uid: postId) { (post) in
if let post = post {
completedPosts.append(post)
}
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .main, execute: {
completion(completedPosts, pagingTemp)
})
}) { (err) in
print("Failed to fetch posts: ", err)
}
}
问题不根源于show()函数,仅仅是因为帖子没有按正确的顺序返回。
然后在collectionView的viewDidLoad方法中调用此loadPosts()函数:
static func show(forKey postKey: String, uid: String, completion: @escaping (Postt?) -> Void) {
let ref = Database.database().reference().child("posts").child(uid).child(postKey)
var images = [String]()
Database.fetchUserWithUID(uid: uid) { (user) in
ref.observeSingleEvent(of: .value, with: { (snapshot) in
guard let post = Postt(snapshot: snapshot) else {
return completion(nil)
}
let imageRef = ref.child("images")
imageRef.observeSingleEvent(of: .value, with: { (imageSnapshot) in
guard let values = imageSnapshot.value as? [String] else {return}
values.forEach({ (value) in
images.append(value)
})
post.imageUrls = images
post.user = user
completion(post)
})
})
}
}