Firestore .startAt无法正常工作

infiniteHandler($state) {
    var next = db
        .collection("posts")
        .orderBy("timestamp", "desc")
        .startAfter(this.lastVisible)
        .limit(3)

    next.get().then(documentSnapshots => {
        //Get the last visible document
        // this.lastVisible =
        // documentSnapshots.docs[documentSnapshots.docs.length - 1]

        if (documentSnapshots.docs.length == 0) $state.complete()
        else {
            this.$store.commit(
                "modules/posts/updateLastVisible",
                documentSnapshots.docs[documentSnapshots.docs.length - 1].data()
                .timestamp
            )
        }

        documentSnapshots.forEach(doc => {
            var post = doc.data()
            post.docID = doc.id
            this.$store.commit("modules/posts/pushPost", post)
        })
        $state.loaded()
    })
}

这是我的无限加载处理程序,一旦到达列表的末尾,它将获取新的数据库条目。到目前为止工作正常。

这是我在页面加载时的第一次提取

async fetch({ store }){
    if (store.state.modules.posts.posts.length < 5) {
        let posts = []
        await db
            .collection("posts")
            .orderBy("timestamp", "desc")
            .limit(3)
            .get()
            .then(querySnapshot => {
                store.commit(
                    "modules/posts/updateLastVisible",
                    querySnapshot.docs[2].data().timestamp
                )
                querySnapshot.forEach(doc => {
                    var x = doc.data()
                    x.docID = doc.id
                    posts.push(x)
                })
            })
        store.commit("modules/posts/fetchedPosts", posts)
    }
}

基本上,问题是当我在无限Loading处理程序中进行获取时,我再次获取了页面加载时获取的前3个条目,这导致条目显示两次,这不应该发生,因为this.lastVisible具有第三个元素的时间戳我是在加载时获取的,因此应该忽略这些内容。

在这些元素之后,一切都可以与一起正常运行,.startAfter但是再次加载前三个元素毫无意义。我使用devtools检查了存储,并且一切正常,this.lastVisible在第一次调用infiniteLoading Handler时它的值正确。

Bounty Edit: Okay so I still have the problem I tried to play around with it a bit more to find the issue but its still occuring... I will set a bounty now and I hope anyone is able to help.

老丝阿飞2020/03/23 22:13:23

好的,所以我找到了一个暂时的解决方案,该解决方案目前可以使用,但仍然不够美观:

documentSnapshots.forEach(doc => {
          if (
            doc.id !== this.posts[0].docID &&
            doc.id !== this.posts[1].docID &&
            doc.id !== this.posts[2].docID
          ) {
            var post = doc.data()
            post.docID = doc.id
            this.$store.commit("modules/posts/pushPost", post)
          }
        })

我也尝试通过不同的解决方案来提高效率,感谢您的帮助。

Stafan2020/03/23 22:13:23

如果您想忽略infiniteHandler中的前3个帖子,则可以创建一个帖子数组,在其中存储帖子ID,并检查帖子ID是否已加载。我知道应该使用查询解决此问题,但作为临时解决方案,我希望它对您有用。

infiniteHandler($state) {
    var next = db
        .collection("posts")
        .orderBy("timestamp", "desc")
        .startAfter(this.lastVisible)
        .limit(3)

    next.get().then(documentSnapshots => {
        //Get the last visible document
        // this.lastVisible =
        // documentSnapshots.docs[documentSnapshots.docs.length - 1]

        if (documentSnapshots.docs.length == 0) $state.complete()
        else {
            this.$store.commit(
                "modules/posts/updateLastVisible",
                documentSnapshots.docs[documentSnapshots.docs.length - 1].data()
                .timestamp
            )
        }

        documentSnapshots.forEach(doc => {
            var check = this.postIdArray.indexOf(doc.id);
            if(check == -1){
                var post = doc.data()
                post.docID = doc.id
                this.$store.commit("modules/posts/pushPost", post);
                this.postIdArray[] = doc.id;
            }
        })
        $state.loaded()
    })
}



async fetch({ store }){
    this.postIdArray = [];
    if (store.state.modules.posts.posts.length < 5) {
        let posts = []
        await db
            .collection("posts")
            .orderBy("timestamp", "desc")
            .limit(3)
            .get()
            .then(querySnapshot => {
                store.commit(
                    "modules/posts/updateLastVisible",
                    querySnapshot.docs[2].data().timestamp
                )
                querySnapshot.forEach(doc => {
                    var x = doc.data()
                    x.docID = doc.id
                    this.postIdArray[] = doc.id;
                    posts.push(x)
                })
            })
        store.commit("modules/posts/fetchedPosts", posts)
    }
}