Reputation: 309
I'm using pagination and therefore using a limit filter. I basically have two functions. A getData() and a updateData(). getData() is called when the app opens to get the first 10 documents of data, sorting them based on a time interval. If the user scrolls down, updateData() is called to retrieve the next 10 documents sorted by the time interval and so on. The sorting is made so that the latest document appears at the top and so on. The problem is that since the data is being limited, it is sorting the first 10 random documents it retrieves from firestore, and not the first 10 documents created out of all the documents. For example, lets say we have documents, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]. When the app loads it would show something like [15, 14, 12, 9, 7, 5, 4, 3, 2, 1]. This is good because it's sorting the data how I want it with the latest document appearing first, but not getting the correct order of documents. Rather it should show [15, 14, 13, 12, 11, 10, 9, 8, 7, 6] What should I do so that when the function runs, out of all the documents surpassing the limit query it receives the actual latest documents in the correct order, and when I update for pagination it continues the process.
getData function:
func getData(){
let db = Firestore.firestore()
let uid = Auth.auth().currentUser!.uid
db.collection("References").whereField("followers", arrayContains: uid).limit(to: 10).getDocuments{ (snap, err) in
if err != nil{
print((err?.localizedDescription)!)
return
}
//Remove shimmer effect
self.data.removeAll()
for i in snap!.documents {
let snippetRef = i.get("ref") as! DocumentReference
let snippetId = i.get("snippetId") as! String
fetchSnippets(id: snippetRef.documentID) { (snippet) in
let data = FeedModel(id: i.documentID, name: i.get("name") as! String, snippet: snippet, snippetId: snippetId, show: false)
self.data.append(data)
//Sort based on time
self.data.sort { (p1, p2) -> Bool in
return p1.snippet.time > p2.snippet.time
}
}
}
self.lastDoc = snap!.documents.last
}
}
updateData function:
func updateData(){
let currentDateTime = Date().timeIntervalSince1970
let user = UserModel(userName: "", profilePic: "", bio: "", displayName: "", snippets: 0, followers: 0, following: 0, mood: "", uid: "", isPublic: false)
let snippet = SnippetModel(caption: "", time: currentDateTime, pic: "", mood: "", uid: "", likes: 0, comments: 0, user: user)
self.data.append(FeedModel(id: "\(self.data.count)", name: "", snippet: snippet, snippetId: "", show: false))
withAnimation(Animation.linear(duration: 1.5).repeatForever(autoreverses: false)){
self.data[self.data.count - 1].show.toggle()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1){
let db = Firestore.firestore()
let uid = Auth.auth().currentUser!.uid
db.collection("References").whereField("followers", arrayContains: uid).start(afterDocument: self.lastDoc).limit(to: 10).getDocuments { (snap, err) in
if err != nil {
print((err?.localizedDescription)!)
return
}
self.data.removeLast()
if !snap!.documents.isEmpty{
for i in snap!.documents{
let snippetRef = i.get("ref") as! DocumentReference
let snippetId = i.get("snippetId") as! String
fetchSnippets(id: snippetRef.documentID) { (snippet) in
let data = FeedModel(id: i.documentID, name: i.get("name") as! String, snippet: snippet, snippetId: snippetId, show: false)
self.data.append(data)
//Sort based on time
self.data.sort { (p1, p2) -> Bool in
return p1.snippet.time > p2.snippet.time
}
}
}
self.lastDoc = snap!.documents.last
}
}
}
}
Upvotes: 1
Views: 549
Reputation: 106
I suggest giving each document a timestamp field. I would modify your query to look something more like this.
db.collection("References").whereField("followers", arrayContains: uid).order(by: "timestamp", descending: true).limit(to: 10)
//put the timeStamp in a global variable
var lastTimestamp: Timestamp?
lastTimeStamp = snapshot.documents?.data()["timestamp"] as! Timestamp
Then, when you make your next request, your query should look something like this
db.collection("References").whereField("followers", arrayContains: uid).whereField("timestamp", isLessThan: lastTimestamp).order(by: "timestamp", descending: true).limit(to: 10)
//then repeat by putting the last documents timestamp into the global variable
lastTimeStamp = snapshot.documents?.data()["timestamp"] as! Timestamp
Upvotes: 2