英文:
What to write in the function so that the sorting is by condition?
问题
我正在使用Firebase编写一个SwiftUI应用程序。文档现在按发布日期排序。需要确保Firebase数据库中包含非空upPostPlusDay数组的文档显示在首位。以下是代码:
用于将数据写入Post数据库的模型:
import SwiftUI
import FirebaseFirestoreSwift
struct Post: Identifiable, Codable, Equatable, Hashable {
@DocumentID var id: String?
var text: String
var postHead: String
var postAddress: String
var imageURL: URL?
var imageReferenceID: String = ""
var publishedDate: Date = Date()
var likedIDs: [String] = []
var dislikedIDs: [String] = []
var plusFavorites: [String] = []
var upPostPlusDay: [Int] = []
var userName: String
var userUID: String
var userProfileURL: URL
var userBioLink: String
enum CodingKeys: CodingKey {
case id
case text
case postHead
case postAddress
case imageURL
case imageReferenceID
case publishedDate
case likedIDs
case dislikedIDs
case plusFavorites
case upPostPlusDay
case userName
case userUID
case userProfileURL
case userBioLink
}
}
向用户输出的代码:
import SwiftUI
import Firebase
struct ReusablePostViewContentView: View {
var basedOnUID: Bool = false
var uid: String = ""
@Binding var posts: [Post]
@State private var isFetching: Bool = true
@State private var paginationDoc: QueryDocumentSnapshot?
var body: some View {
ScrollView (.vertical, showsIndicators: false) {
LazyVStack {
if isFetching {
ProgressView()
.padding(.top, 30)
} else {
if posts.isEmpty {
Text("No posts")
.font(.caption)
.foregroundColor(.gray)
.padding(.top, 30)
} else {
Posts()
}
}
}
.padding(15)
}
.refreshable {
guard !basedOnUID else {return}
isFetching = true
posts = []
paginationDoc = nil
await fetchPosts()
}
.task {
guard posts.isEmpty else {return}
await fetchPosts()
}
}
@ViewBuilder
func Posts() -> some View {
ForEach (posts) { post in
PostCardViewContentView(postDog: post) { updatedPost in
if let index = posts.firstIndex(where: { post in
post.id == updatedPost.id
}) {
posts[index].likedIDs = updatedPost.likedIDs
posts[index].dislikedIDs = updatedPost.dislikedIDs
}
} onDelete: {
withAnimation(.easeInOut(duration: 0.25)) {
posts.removeAll {post.id == $0.id}
}
}
.onAppear {
if post.id == posts.last?.id && paginationDoc != nil {
Task {await fetchPosts()}
// print("fetch new posts")
}
}
Divider()
.padding(.horizontal, -15)
}
}
func fetchPosts() async {
do {
var query: Query!
if let paginationDoc {
query = Firestore.firestore().collection("Posts")
.order(by: "publishedDate", descending: true)
.start(afterDocument: paginationDoc)
.limit(to: 5)
} else {
query = Firestore.firestore().collection("Posts")
.order(by: "publishedDate", descending: true)
.limit(to: 5)
}
if basedOnUID {
query = query.whereField("userUID", isEqualTo: uid)
}
let docs = try await query.getDocuments()
let fetchedPosts = docs.documents.compactMap { doc -> Post? in
try? doc.data(as: Post.self)
}
await MainActor.run(body: {
posts.append(contentsOf: fetchedPosts)
paginationDoc = docs.documents.last
isFetching = false
})
} catch {
print(error.localizedDescription)
}
}
}
希望这有所帮助。如果您有任何问题,请随时提问。
英文:
I am writing a swiftui application using firebase. Documents are now sorted by publication date. It is necessary that documents that contain a non-empty upPostPlusDay array in the Firebase database are shown in the first place. Here is the code.
Model for writing data to the Post database:
import SwiftUI
import FirebaseFirestoreSwift
struct Post: Identifiable, Codable, Equatable, Hashable {
@DocumentID var id: String?
var text: String
var postHead: String
var postAddress: String
var imageURL: URL?
var imageReferenceID: String = ""
var publishedDate: Date = Date()
var likedIDs: [String] = []
var dislikedIDs: [String] = []
var plusFavorites: [String] = []
var upPostPlusDay: [Int] = []
var userName: String
var userUID: String
var userProfileURL: URL
var userBioLink: String
enum CodingKeys: CodingKey {
case id
case text
case postHead
case postAddress
case imageURL
case imageReferenceID
case publishedDate
case likedIDs
case dislikedIDs
case plusFavorites
case upPostPlusDay
case userName
case userUID
case userProfileURL
case userBioLink
}
}
Output code to user:
import SwiftUI
import Firebase
struct ReusablePostViewContentView: View {
var basedOnUID: Bool = false
var uid: String = ""
@Binding var posts: [Post]
@State private var isFetching: Bool = true
@State private var paginationDoc: QueryDocumentSnapshot?
var body: some View {
ScrollView (.vertical, showsIndicators: false) {
LazyVStack {
if isFetching {
ProgressView()
.padding(.top, 30)
} else {
if posts.isEmpty {
Text("No posts")
.font(.caption)
.foregroundColor(.gray)
.padding(.top, 30)
} else {
Posts()
}
}
}
.padding(15)
}
.refreshable {
guard !basedOnUID else {return}
isFetching = true
posts = []
paginationDoc = nil
await fetchPosts()
}
.task {
guard posts.isEmpty else {return}
await fetchPosts()
}
}
@ViewBuilder
func Posts() -> some View {
ForEach (posts) { post in
PostCardViewContentView(postDog: post) { updatedPost in
if let index = posts.firstIndex(where: { post in
post.id == updatedPost.id
}) {
posts[index].likedIDs = updatedPost.likedIDs
posts[index].dislikedIDs = updatedPost.dislikedIDs
}
} onDelete: {
withAnimation(.easeInOut(duration: 0.25)) {
posts.removeAll {post.id == $0.id}
}
}
.onAppear {
if post.id == posts.last?.id && paginationDoc != nil {
Task {await fetchPosts()}
// print("fetch new posts")
}
}
Divider()
.padding(.horizontal, -15)
}
}
func fetchPosts() async {
do {
var query: Query!
if let paginationDoc {
query = Firestore.firestore().collection("Posts")
.order(by: "publishedDate", descending: true)
.start(afterDocument: paginationDoc)
.limit(to: 5)
} else {
query = Firestore.firestore().collection("Posts")
.order(by: "publishedDate", descending: true)
.limit(to: 5)
}
if basedOnUID {
query = query.whereField("userUID", isEqualTo: uid)
}
let docs = try await query.getDocuments()
let fetchedPosts = docs.documents.compactMap { doc -> Post? in
try? doc.data(as: Post.self)
}
await MainActor.run(body: {
posts.append(contentsOf: fetchedPosts)
paginationDoc = docs.documents.last
isFetching = false
})
} catch {
print(error.localizedDescription)
}
}
}
Help me please.
答案1
得分: 0
需要在Firebase数据库中显示包含非空upPostPlusDay数组的文档排在第一位。没有可以添加到Firestore查询的子句,可以将具有特定非空数组的文档排在前面,同时获取所有其他文档。
解决方案是(通常在使用NoSQL数据库时)更改/扩展数据模型以支持该用例。
例如,如果您为每个文档添加一个字段upPostPlusDayValueCount
,并在该字段中保持实时计数,您可以按降序upPostPlusDayValueCount
排序,以获取具有非空upPostPlusDay
数组的文档在结果开头的文档。
英文:
> It is necessary that documents that contain a non-empty upPostPlusDay array in the Firebase database are shown in the first place
There is no clause that you can add to a Firestore query to get documents with a specific non-empty array first, while also getting all other documents.
The solution is (as usual when working with NoSQL databases) to change/expand your data model to allow the use-case.
For example, if you add a field upPostPlusDayValueCount
to each document, and keep an up-to-date count in that field, you can sort on descending upPostPlusDayValueCount
to get the documents with a non-empty upPostPlusDay
array at the start of the results.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论