繁体   English   中英

如何使用限制过滤器 Firestore 对数据进行排序

[英]How to sort data with a limit filter Firestore

我正在使用分页,因此使用了限制过滤器。 我基本上有两个功能。 getData() 和 updateData()。 getData() 在应用程序打开时调用以获取数据的前 10 个文档,并根据时间间隔对它们进行排序。 如果用户向下滚动,将调用 updateData() 以检索按时间间隔排序的下 10 个文档,依此类推。 排序是为了让最新的文档出现在顶部等等。 问题在于,由于数据有限,它正在对从 firestore 检索到的前 10 个随机文档进行排序,而不是对所有文档中创建的前 10 个文档进行排序。 例如,假设我们有文档 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]。 当应用程序加载时,它会显示类似 [15, 14, 12, 9, 7, 5, 4, 3, 2, 1] 的内容。 这很好,因为它按照我想要的方式对数据进行排序,最新的文档首先出现,但没有得到正确的文档顺序。 相反,它应该显示 [15, 14, 13, 12, 11, 10, 9, 8, 7, 6] 我应该怎么做才能在 function 运行时,在超过限制查询的所有文档中,它收到实际最新的以正确的顺序记录文件,当我更新分页时,它会继续这个过程。

获取数据 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
            
        }
        
        
    }

更新数据 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
                }
                
            }
        }
    }

我建议给每个文档一个时间戳字段。 我会修改您的查询,使其看起来更像这样。

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

然后,当您发出下一个请求时,您的查询应该看起来像这样

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM