【问题标题】:Firebase StartAfter in query not working as expected查询中的 Firebase StartAfter 未按预期工作
【发布时间】:2021-05-27 23:37:06
【问题描述】:

我使用 firebase firestore 作为我的数据库,并且我已经编写了 firebase 函数来从 firestore 数据库中检索数据。

我想要实现的是分页,并且根据文档,我已经为我的 firebase 函数实现了代码。下面是代码:

exports.getBillList = functions.https.onRequest((req, res) => {
    let docs=[]; 
    let limit = 15;
    return cors(req, res, () => {
        let lastBillInList=req.query.lastBillInList;
        console.log("lastBillInList value: " + lastBillInList);
        if (lastBillInList === null || lastBillInList === undefined) lastBillInList = 0;
        //var lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1];
      if(lastBillInList==0){
          console.log('first time call: as no lastbillseqq');
        db.collection("bills").orderBy('billNo','desc').limit(limit).get().then(function (querySnapshot) {
            querySnapshot.forEach(function (doc) {

                docs.push(doc.data());
            });
            res.status(200).send(docs);
        }).catch(function (error) {
            console.error("Error getting list: ", error);
            res.status(500).send();
        });
    }else{
          console.log('second time call: as no lastbillseqq'+ lastBillInList);
        db.collection("bills").orderBy('billNo', 'desc').startAfter(lastBillInList).limit(limit).get().then(function (querySnapshot) {
            querySnapshot.forEach(function (doc) {

                docs.push(doc.data());
            });
            res.status(200).send(docs);
        }).catch(function (error) {
            console.error("Error getting list: ", error);
            res.status(500).send();
        });
    }
    });

});

我在我的 firebase 函数中添加了条件,它检查是否提供了最后一个账单号码。

如果是,则检索最后一个账单之后的所有账单记录,直到设置的限制,否则如果没有提供最后一个账单编号,则将其视为第一个请求并检索初始记录直到限制

但是我面临的问题是,无论执行 else 部分的代码如何,当提供最后一个账单编号时,查询总是返回从结果开始到指定限制的记录。由于某种原因 StartAfter 无法正常工作

例如,我有账单编号为 1 到 25 的记录,我在上面的代码中按降序排列,所以结果是从账单编号 25 到 1。

当没有提供账单编号时,我会得到从 25 到 11 的账单编号结果。 当我提供帐单编号时,我会从帐单编号 25 到 11 得到结果,而不是从 10 到 1 的预期帐单编号。

谁能帮我解决这个问题?

【问题讨论】:

  • 还有很多事情需要做,我不确定我是否理解发生了什么。你能重现这个:1)在一个常规的 Node.js 脚本中,所以没有 Cloud Functions? 2) 使用硬编码值代替变量(例如lastBillInListlimit )? 3) 向我们展示实际文件,而不是描述它们? 4) 只有一个条件(ifelse 块)。所有这些都有助于minimal complete verifiable example 并使其更有可能有人发现问题所在。

标签: javascript firebase pagination google-cloud-firestore google-cloud-functions


【解决方案1】:

我可以通过以下代码进行分页。在我的模型对象中,我使用了 Document ID,据此我找到了 documentReference -> documentSnapshot。我终于使用 documentSnapshot 进行比较(这是我的错误,因为之前我没有使用 documentSnapshot)以获得所需的输出。

下面是我的代码:

exports.getBillList = functions.https.onRequest((req, res) => {


console.log("----------------------------------function start");

    let docs = [];
    let lastBillInList=req.query.lastBillInList;
    if(lastBillInList===undefined){
        lastBillInList="noDocument";
    }
    let limit = 15;

    return cors(req, res, () => {


        var lastVisible = db.collection("bills").doc(lastBillInList);


        lastVisible.get().then(function (doc) {
            if (doc.exists) {
                db.collection("bills")
                    .orderBy("billNo", "desc")
                    .startAfter(doc)
                    .limit(limit).get().then(function(querySnapshot){

                        querySnapshot.forEach(function (doc) {
                            //console.log(doc.data().billNo + " pushed.." + ": last bill was: " + tempBill);


                            docs.push(doc.data());
                        });
                        return res.status(200).send(docs);

                    });
            } else {
                db.collection("bills")
                    .orderBy("billNo", "desc")
                    .limit(limit).get().then(function (querySnapshot) {

                        querySnapshot.forEach(function (doc) {

                            docs.push(doc.data());
                        });
                        return res.status(200).send(docs);

                    });
            }
        }).catch(function (error) {
            console.log("Error getting document:", error);
            return res.status(500).send();
        });

    console.log("----------------------------------function end");
});
});

【讨论】:

  • 通过这个例子,端点会是什么样子?请举个例子
【解决方案2】:

好的,我发现了一个有趣的点。您必须在limit(to:) 之前调用start(afterDocument:),否则它将无法按预期工作。 所以应该是这样的:

db.collection("collection")
    .order(by: "createdAt", descending: true)
    .start(afterDocument: snapshot) // This is where you need to put start
    .limit(to: Constants.Database.Feed.limit)
    .getDocuments { (snapshot, error) in
        // some useful stuff
    }

【讨论】:

    猜你喜欢
    • 2016-10-14
    • 2017-06-24
    • 2012-11-13
    • 2021-07-15
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多