static func fetchFeedPostsWithPagination(lastDocument: DocumentSnapshot?, limit: Int) async throws -> (posts: [Post], lastDocument: DocumentSnapshot?) {
let uid = Auth.auth().currentUser?.uid
let currentUser = try await UserService.fetchUser(withUid: uid ?? "")
let userCategories = currentUser.categories?.keys.map { $0 } ?? [] // Convert keys to an array
var query: Query = postsCollection
if !userCategories.isEmpty {
query = query.whereField("category", in: userCategories)
}
query = query.order(by: "timestamp", descending: true)
query = query.limit(to: limit)
if let lastDocument = lastDocument {
query = query.start(afterDocument: lastDocument)
}
let snapshot = try await query.getDocuments()
var posts = try snapshot.documentspactMap { try $0.data(as: Post.self) }
for i in 0 ..< posts.count {
let ownerUid = posts[i].ownerUid
let postUser = try await UserService.fetchUser(withUid: ownerUid)
posts[i].user = postUser
}
let lastDoc = snapshot.documents.last
return (posts, lastDoc)
}
I’ve tried using .order to prioritize posts based on categories in a user’s array of interests, but I can’t figure out how to implement it correctly. Additionally, I want to maintain pagination since there will be a large number of posts, and I don’t want to fetch them all at once. How can I achieve this?
static func fetchFeedPostsWithPagination(lastDocument: DocumentSnapshot?, limit: Int) async throws -> (posts: [Post], lastDocument: DocumentSnapshot?) {
let uid = Auth.auth().currentUser?.uid
let currentUser = try await UserService.fetchUser(withUid: uid ?? "")
let userCategories = currentUser.categories?.keys.map { $0 } ?? [] // Convert keys to an array
var query: Query = postsCollection
if !userCategories.isEmpty {
query = query.whereField("category", in: userCategories)
}
query = query.order(by: "timestamp", descending: true)
query = query.limit(to: limit)
if let lastDocument = lastDocument {
query = query.start(afterDocument: lastDocument)
}
let snapshot = try await query.getDocuments()
var posts = try snapshot.documentspactMap { try $0.data(as: Post.self) }
for i in 0 ..< posts.count {
let ownerUid = posts[i].ownerUid
let postUser = try await UserService.fetchUser(withUid: ownerUid)
posts[i].user = postUser
}
let lastDoc = snapshot.documents.last
return (posts, lastDoc)
}
I’ve tried using .order to prioritize posts based on categories in a user’s array of interests, but I can’t figure out how to implement it correctly. Additionally, I want to maintain pagination since there will be a large number of posts, and I don’t want to fetch them all at once. How can I achieve this?
Share Improve this question edited Feb 1 at 23:27 Frank van Puffelen 600k85 gold badges889 silver badges859 bronze badges Recognized by Mobile Development Collective and Google Cloud Collective asked Feb 1 at 21:36 CobraCodesCobraCodes 391 silver badge5 bronze badges 4 |1 Answer
Reset to default 1You can't use a single query to get both the posts that the user is interested in and those that don't match their interests; the two query criteria are opposite.
Since you want to show the "interesting" posts first, followed by the remainders, you can use two queries.
- First, request posts with
query.whereField("category", in: userCategories)
- Once you have retrieved all of these documents, then you can issue a new query
query.whereField("category", notIn: userCategories)
- You can be sure that none of these documents were in the initial query.
in
or you are not. Your result set can't include results that don't match the query. What is the desired behaviour? If there are, say, 1000 posts, and the oldest post matches one of the user's interests and the newest doesn't, should the oldest post be shown before the newest post? I think you would need to keep fetching documents until the query returns nothing, and then start a new query usingnot in
instead ofin
– Paulw11 Commented Feb 1 at 21:42