Firestore 排序列表 - 重复 API 调用 Firestore X 次以迭代 Firestore 文档的链接列表

Firestore sorted list - Repeat API call to Firestore X times to iterate over a linked list of Firestore documents

我正在 Firestore 中试验一个“链接列表”,它维护一个排序的事务列表。我期待大量的交易,所以我在玩无限滚动的想法,在初始加载时我们拉入最近的 X 笔交易,然后根据需要分批加载更多。

Transactions 是一个文档集合,每个文档代表一个交易。每个文档都包含对下一个文档名称的引用(即下一个最近的交易)。

例如,

Transaction A
  nextDocId: 'Transaction B'
Transaction B
  nextDocId: 'Transaction C'
Transaction C
  nextDocId: 'Transaction D'

给定起始交易,加载 X 交易的最佳方式是什么?如果我只是为 X 选择一个值(比如 10),我可以将 10 switchMaps/concatMaps 链接在一起,但是有没有办法动态地做到这一点?我基本上需要重复 API 调用 X 次,但每次调用都需要上次调用的响应。

或者,这个解决方案是否可行?我没有看到任何其他方法来维护 Firestore 中的排序列表,因此另一种选择是每次都对客户端中的整个事务列表进行排序。

你应该看看 expand operator. You can use the operator as described in the excellent article (rxjs core team member) here: expand explained

在示例中,获取了下一页(在您的交易案例中)one-by-one。我试图找到一个建议。

我终于使用 expandbufferCount 完成了这项工作。有一些技巧,第一个是在它自己的函数中定义 Firestore 调用以使递归按预期工作,

private getNextTransactionRequest(txnId: string): Observable<any> {
    return this.firestore.collection('myCollection').doc(txnId).snapshotChanges().pipe(
        map(response => {
            return response.payload.data();
        })
    );
}

然后,将调用串在一起,

public loadTransactions(headTxnId: string, n: number): Observable<any[]> {
    const getNextTransaction$ = this.getNextTransactionRequest(headTxnId);
    return getNextTransaction$.pipe(
        expand(txn => {
            if (txn) {
                if (txn.nextTransactionId && txn.nextTransactionId != '') {
                    return this.getNextTransactionRequest(txn.nextTransactionId);
                }
            }
        }),
        bufferCount(n),
        take(1)
    );
}

expand 使用上一次调用的响应递归地将 API 调用链接在一起,这正是我所需要的,并且 bufferCount 一直等到 [=29= 的上一个链] calls 发出了 n 个事务并立即将其作为数组发出。

bufferCount 的一个问题是如果 nTransactions % n != 0 您将丢失一些交易。为了解决这个问题,我想我只是要跟踪交易总数和我已经加载的总数。那么如果nTotal - nLoaded < n我就设置n = nTotal - nLoaded.