Firebase管理员无法查询大型物品



使用firebase admin从云功能中的集合中检索数据对大型项目失败。我用来查询云功能选择的示例代码如下

admin.database().orderByChild('mmyyyy').equalTo(month).once('value');

当我尝试检索10600个项目时,此呼叫失败(试图找出原因)。在Google控制台中,有此日志,但没有其他可以将我指向正确方向

textPayload:  "Function execution took 18547 ms, finished with status: 'response error'"   

尝试失败后,我决定使用Firebase SDK在客户端执行此呼叫,如下所示:

result = await firebase.database().ref(`transactions`).orderByChild('mmyyyy').equalTo(month).once('value');

这在客户端完美地工作,没有错误并返回我所有的17000个项目(此JSON的大小为26MB)。

为什么这样?有没有记录的限制?

注意:我将云功能内存增加到1GB,超时到5分钟,没有帮助。

这是完整的示例代码

const admin = require('firebase-admin');
var functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
const cors = require('cors')({
    "origin": "*",
    "methods": "POST,GET",
    "allowedHeaders": "Content-Type,uid,agence,month,course,raceType,raceNumber,status",
    "preflightContinue": false,
    "optionsSuccessStatus": 204
});
function _findTransactions(agence, month, course, raceType, raceNumber, status) {
    return new Promise((resolve, reject) => {
        try {
            let db = admin.database();
            let findPromise = db.ref(`transactions`).orderByChild('mmyyyy').equalTo(month).once('value');
            findPromise.then((result) => {
                let transactions = result.val();
                //removed business logic
                resolve(transactions);
            }).catch((err) => {
                console.log(err);
                reject(err);
            });
        } catch (error) {
            console.log(error);
            reject(error);
        }
    });
}
exports.findTransactions = functions.https.onRequest((req, res) => {
    let uid;
    try {
        cors(req, res, () => {
            uid = req.headers.uid;
            let agence = req.headers.agence;
            let month = req.headers.month;
            let course = req.headers.course;
            let raceType = req.headers.raceType;
            let raceNumber = req.headers.raceNumber;
            let status = req.headers.status;
            if (req.method !== 'GET') {
                return handleResponse(req, res, 403);
            }
            if (!uid || uid == null || uid == undefined) {
                return handleResponse(req, res, 401);
            }
            _validateUserId(uid, ['central_cashier', 'admin'])
                .then(() => {
                    _findTransactions(agence, month, course, raceType, raceNumber, status)
                        .then((result) => {
                            return handleResponse(req, res, 200, result);
                        }).catch((error) => {
                            return handleResponse(req, res, 500);
                        });
                }).catch((error) => {
                    return handleResponse(req, res, 401);
                });
        });
    } catch (error) {
        return handleError(res, uid, error);
    }
});

您的有效载荷太大,如您所述,超出了Google Cloud功能的配额。

想到了两个选项:

  • 压缩有效载荷。 GZIP在将文件发送给客户端之前。对于Zlib模块中构建的NodeJS,;
  • 很容易
  • 设置虚拟机。虚拟机不受这些限制。

我进行了一些测试,得出结论,当查询产生大量结果时,Google Cloud功能(GCF)正在执行某种超时或"流产"操作(即许多数据存储实体)。有关某些背景,请参阅我在这个问题上附带的评论。

tl; dr i创建了我自己的Express.js Web服务器,并在其上运行了我的GCF代码。

这是我测试的方式:我使用HTTP/HTTPS创建了一个Ubuntu实例,并启用了DataStore API。在我的情况下,我安装了节点,表达并获得了基本的HTTPS服务器(自签名证书工作正常,因为这只是测试API后端服务)。然后,我将我的GCF代码(在GCF中失败的功能)复制到我的Minimal Express Web服务器中。我指出了我的React应用程序使用我的实例,该应用程序触发了一个查询,从而产生了32,000多个数据存储实体。我的GCF函数发送了一个常见的datastore.runQuery()查询。

花了大约一分钟的时间,但最终所有32,000个实体都用Express提供并加载在React App(浏览器)中,没有错误。

基本的快速路由调用我的GCF函数:

app.post('/foo', (req, res) => {
  myCloudFunction(req, res);
})
const myCloudFunction = (req, res) => {
  // Inspects req, queries Datastore, and returns the results.
};

对于此测试,我的React应用只指向https://mydomain.example.com:3000/foo(因为我的Express服务器在端口3000上听)。

所以GCF似乎不够好,除非我在应用程序上添加分页(在路线图上)。

相关内容

  • 没有找到相关文章

最新更新