【问题标题】:Firestore pagination startAfter(DocumentSnapshot) working in java but not in kotlinFirestore 分页 startAfter(DocumentSnapshot) 在 java 中工作但在 kotlin 中没有
【发布时间】:2021-01-21 09:23:42
【问题描述】:

我正在尝试将一个 Android Firestore 项目从 java 转换为 kotlin。但是陷入了分页部分,其中带有 java 代码的 startAfter(DocumentSnapshot) 工作正常。但是 kotlin 只给出前 3 个结果。 StartAfter(DocumentSnapshot) 部分不起作用。

如果您能指出我在 Kotlin 中哪里出了问题,那将非常有帮助。

这是完美运行的java代码

 public void loadNotes(View v) {
    Query query;
    if (lastResult == null) {
        query = notebookRef.orderBy("priority")
                .limit(3);
    } else {
        query = notebookRef.orderBy("priority")
                .startAfter(lastResult)
                .limit(3);
    }
    Log.d(TAG, "loadNotes: "+ query);
    query.get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                    String data = "";
                    for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
                        Notee note = documentSnapshot.toObject(Notee.class);
                        note.setDocumentId(documentSnapshot.getId());
                        String documentId = note.getDocumentId();
                        String title = note.getTitle();
                        String description = note.getDescription();
                        int priority = note.getPriority();
                        data += "ID: " + documentId
                                + "\nTitle: " + title + "\nDescription: " + description
                                + "\nPriority: " + priority + "\n\n";
                    }
                    if (queryDocumentSnapshots.size() > 0) {
                        data += "___________\n\n";
                        textViewData.append(data);
                        lastResult = queryDocumentSnapshots.getDocuments()
                                .get(queryDocumentSnapshots.size() - 1);
                    }
                }
            });
}

这是 Kotlin,它不起作用。

 private fun loadNotes() {
    val query = if (lastResult == null) {
        notebookRef
            .orderBy("priority")
            .limit(3)
    } else {
        Log.d(TAG, "loadNotes: ${lastResult!!.id}")
        notebookRef
            .orderBy("priority")
            .startAfter(lastResult)
            .limit(3)

    }

    Log.d(TAG, "loadNotes: $query")


    query.get()
        .addOnSuccessListener { QuerySnapshot ->
            var text = ""
            for (queryDocumentSnapshot in QuerySnapshot) {
                val note: Note = queryDocumentSnapshot.toObject(Note::class.java)
                note.docID = queryDocumentSnapshot.id

                val title = note.title
                val description = note.description
                val priority = note.priority
                text += "ID: ${note.docID} \n Title : $title\n Description :$description\n" +
                        "Priority :$priority \n"

            }
            if (QuerySnapshot.size() > 0) {
                text += "---------------\n\n"
                textView_data.append(text)
                lastResult = QuerySnapshot.documents[QuerySnapshot.size() - 1]
            }
        }
}

希望得到帮助

谢谢

测试所需代码:JavaActivityKotlinActivityNote Modelactivity_main.xml

【问题讨论】:

  • 对于真正的 kotlin 支持,您可以将 onSucessListeners 替换为 kotlin coroutines. here 是一个示例

标签: android kotlin google-cloud-firestore pagination


【解决方案1】:

您的代码按预期工作。你在 Java 的 Kotlin 中所做的事情没有区别。在这两种情况下,您都将限制指定为 3。

如果有什么问题,那将是你的逻辑。

【讨论】:

  • 我的逻辑是正确的,这就是为什么我明确提到java代码工作正常。
  • @Shijilal java 代码中的查询部分与 kotlin 代码中的相同,并且应该给出相同的结果。如果有问题,那就是代码的另一部分。
  • 它只是一个按钮点击,不受其他代码的影响。我已按问题更新了所有必需的代码,以进行检查和测试。
【解决方案2】:

您必须在 Kotlin 中以不同的方式实现它。而不是保留对最后一个结果的引用,您必须保留对使用 lastResult 创建的查询的引用。

移除全局 lastResult 并替换为:

private var query: Query? = null

然后像这样实现 LoadNotes:

private fun loadNotes() {
    if(query == null){
        query = notebookRef.orderBy("priority").limit(3)
    }
    query!!.get().addOnSuccessListener { QuerySnapshot ->
        var text = ""
        for (queryDocumentSnapshot in QuerySnapshot) {
            val note: Note = queryDocumentSnapshot.toObject(Note::class.java)
            note.docID = queryDocumentSnapshot.id

            val title = note.title
            val description = note.description
            val priority = note.priority
            text += "ID: ${note.docID}\nTitle: $title \nDescription: $description"+
            "\nPriority: $priority\n"

        }
        if (QuerySnapshot.size() > 0) {
            text += "---------------\n\n"
            textView_data.append(text)
            val lastResult = QuerySnapshot.documents[QuerySnapshot.size() - 1]
            query = notebookRef.orderBy("priority").startAfter(lastResult).limit(3)
        }
    }
}

最后两行是它起作用的原因。老实说,我仍然不明白为什么它不像 Java 那样工作,但至少这个实现是有效的。 firebase documentation 也建议这样实现。

【讨论】:

  • 谢谢。有效。但问题仍然存在,为什么早期的代码不起作用。 :(
【解决方案3】:

好吧,在遇到同样的问题之后。它是通过使用非空强制转换 (!!) 解决的。例如:

val query = transactionsCollection
            .orderBy(Field.CREATED, Query.Direction.DESCENDING)
            .startAfter(lastDocument!!)
            .limit(PAGE_SIZE)

在你的情况下是:

 query = notebookRef.orderBy("priority")
                .startAfter(lastResult!!)
                .limit(3);

它正在使用 Kotlin。

【讨论】:

  • 终于找到了唯一可行的答案!万分感谢! (我不确定为什么它一开始就不起作用)。
猜你喜欢
  • 2020-01-15
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多