使用firebase admin从云功能中的集合中检索数据对于大型项目失败。我用来查询云功能选择的示例代码如下
admin.database().orderByChild('mmyyyy').equalTo(month).once('value');
当我尝试检索10600个项目(试图找出原因)时,此调用失败。在谷歌控制台中有这个日志,但没有任何其他可以指向我正确的方向
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);
}
});

答案 0 :(得分:2)
您的有效负载过大,如您所述exceeding the quota for Google Cloud Functions。
想到两个选择:
答案 1 :(得分:1)
我进行了一些测试,得出的结论是,当查询产生大量结果(例如,许多数据存储区实体)时,Google Cloud Functions(GCF)正在执行某种超时或“中止”操作。有关某些背景,请参阅我对此问题的评论。
tl; dr我创建了自己的Express.js网络服务器,并在其上运行了我的GCF代码。
这是我的测试方式:我创建了一个使用http / https和Datastore API启用的ubuntu实例。在我的实例上,我安装了Node,Express,并运行了基本的https服务器(自签名证书运行良好,因为这只是测试api后端服务)。然后,我将我的GCF代码(在GCF中失败的功能)复制粘贴到我的最小Express网络服务器中。我指出我的React应用程序使用我的实例,该实例触发了一个查询,该查询导致了超过32,000个Datastore实体。我的GCF函数使用常见的datastore.runQuery()
发送查询。
花了大约一分钟,但最终所有32,000个实体都由Express提供服务,并没有错误地加载到React应用程序(浏览器)中。
一条基本的Express路由调用了我的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似乎对我的应用程序还不够好。