【问题标题】:Firestore not ordering my results depending on timestampFirestore 不根据时间戳对我的结果进行排序
【发布时间】:2021-08-08 15:29:22
【问题描述】:

我正在尝试先获取我所有的帖子,哪个时间是较新的,我已经进行了这个查询,应该将我上传或其他人发布的所有最新帖子带给我。

问题是我收到的帖子是用时间戳打乱的,都是混在一起的,而不是按新的排序

如果我从 firebase 控制台执行相同的查询,它们会按应有的方式排序

我的recyclerview NOT 有任何 reverselayoutstackfromend 属性,我不希望使用它们,而是我只希望我的列表来自 firebase 排序

@ExperimentalCoroutinesApi
    suspend fun getLatestPosts(): Flow<Result<List<Post>>> = callbackFlow {

        val postList = mutableListOf<Post>()

        // Reference to use in Firestore
        var eventsCollection: CollectionReference? = null
        try {
            eventsCollection = firestore.collection("posts")
            eventsCollection.orderBy("created_at", Query.Direction.DESCENDING)
        } catch (e: Throwable) {
            // If Firebase cannot be initialized, close the stream of data
            // flow consumers will stop collecting and the coroutine will resume
            close(e)
        }

        val suscription = eventsCollection?.addSnapshotListener { value, error ->
            if (value == null) {
                return@addSnapshotListener
            }

            try {
                postList.clear()
                for (post in value.documents) {
                    post.toObject(Post::class.java)?.let { fbPost ->
                        fbPost.apply {
                            created_at = post.getTimestamp(
                                "created_at",
                                DocumentSnapshot.ServerTimestampBehavior.ESTIMATE
                            )?.toDate()
                        }
                        postList.add(fbPost)
                    }
                }
                offer(Result.Success(postList))
            } catch (e: Exception) {
                close(e)
            }
        }

        awaitClose { suscription?.remove() }
    }

现在,如果我在获取有效数据后在本地对列表进行排序,但我不希望它是客户端,我希望从服务器获得一个有序列表。

我做错了什么?

帖子时间戳以 @ServerTimestamp 和日期格式保存到 Firestore 中

【问题讨论】:

    标签: android firebase kotlin google-cloud-firestore


    【解决方案1】:

    CollectionReference(查询)对象是不可变的——一旦创建就无法更改。他们使用构建器类型模式通过添加约束来构造新的 Query 对象。原始查询保持不变。

    如果您想组合一组操作来对 Query 执行,您必须记住每个操作返回的新 Query。一个简单的方法是在不再需要之前重新分配之前的查询:

    var eventsQuery: Query = firestore.collection("posts")
    eventsQuery = eventsQuery.orderBy("created_at", Query.Direction.DESCENDING)
    

    或者您可以将其作为一个链式操作序列来执行,这在您提前知道所有操作的情况下更为惯用:

    val eventsQuery = firestore
        .collection("posts")
        .orderBy("created_at", Query.Direction.DESCENDING)
    

    但是,如果您需要有条件地应用操作,则需要采用第一种方法。更详细的解释可以在这里找到:Firestore: Multiple conditional where clauses

    【讨论】:

      【解决方案2】:

      问题出在这一行

      eventsCollection = firestore.collection("posts")
      eventsCollection.orderBy("created_at", Query.Direction.DESCENDING)
      

      似乎我需要将其全部包装成 1 行并使其成为 Query,它不会对 eventsCollection 进行任何更改,这可以通过将 CollectionReference 更改为 Query 来完成

      【讨论】:

      • 它不一定是一行,但拥有这一行是无操作的:eventsCollection.orderBy("created_at", Query.Direction.DESCENDING)。这是因为所有orderBywhere... 方法都是构建器,并返回一个新的Query 对象(而不是修改现有对象)。因此,您可以拥有多行,方法是:1)将eventsCollection 的类型更改为Query(就像您所做的那样)。 2) 然后将构建器的结果分配返回给变量,例如:eventsCollection = eventsCollection.orderBy("created_at", Query.Direction.DESCENDING)
      猜你喜欢
      • 1970-01-01
      • 2021-08-02
      • 2018-08-09
      • 2012-07-15
      • 1970-01-01
      • 2020-04-15
      • 2013-03-06
      • 2014-05-01
      • 2019-11-11
      相关资源
      最近更新 更多