我有以下代码,可以根据给定的一些参数获取随机 Firestore 文档
const { onSchedule } = require("firebase-functions/v2/scheduler");
const { logger } = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
var db = admin.firestore();
function getRandomFromCollection(collection, level, enabled) {
return new Promise(function (resolve, reject) {
logger.info("Starting random search")
let key = collection.doc().id;
logger.info("random key done");
collection.where("enabled", "==", enabled).where("level", "==", level).where("__name__", '>=', key).limit(1).get()
.then(snapshot => {
if (snapshot.size > 0) {
snapshot.forEach(doc => {
logger.info("done");
resolve(doc);
});
}
else {
collection.where("enabled", "==", enabled).where("level", "==", level).where("__name__", '<', key).limit(1).get()
.then(snapshot => {
snapshot.forEach(doc => {
logger.info("done");
resolve(doc);
});
})
.catch(err => {
logger.info("error");
reject(err);
});
}
})
.catch(err => {
logger.info("error");
reject(err);
});
});
}
exports.newQuestions = onSchedule({
schedule: "every day 9:55",
maxInstances: 1,
timeZone: "UTC"
},
async (event) => {
let collection = db.collection("questions");
getRandomFromCollection(collection, 1, false).then(doc => {
logger.info("Got question");
}).catch(err => {
logger.error(`ERROR! Something when wrong when generating question! Error: ${err}`)
})
});
我已经在函数模拟器中多次运行此代码,没有出现任何问题,但是当我将其部署到 firebase 并每天运行一次时,似乎每 5 个调用中就有 1 个会失败。
发生错误时,函数日志显示“开始随机搜索”和“随机密钥完成”,但随后不返回任何其他内容,并且承诺未解决或拒绝。
自从您使用
async
关键字以来,我已经重写了您的 CF,如下所示。如有必要,请随时对此答案添加评论,以便我们可以微调此提议的解决方案。
async function getRandomFromCollection(collection, level, enabled) {
logger.info("Starting random search");
let key = collection.doc().id;
logger.info("random key done");
const snapshot = await collection
.where("enabled", "==", enabled)
.where("level", "==", level)
.where("__name__", ">=", key)
.limit(1)
.get();
if (snapshot.size > 0) {
// No need to use snapshot.forEach since there is only 1 doc in the querySnapshot if snapshot.size > 0
return snapshot.docs[0];
} else {
const snapshot = await collection
.where("enabled", "==", enabled)
.where("level", "==", level)
.where("__name__", "<", key)
.limit(1)
.get();
if (snapshot.size > 0) {
return snapshot.docs[0];
}
}
}
exports.newQuestions = onSchedule(
{
schedule: "every day 9:55",
maxInstances: 1,
timeZone: "UTC",
},
async (event) => {
try {
let collection = db.collection("questions");
await getRandomFromCollection(collection, 1, false);
logger.info("Got question");
return true;
} catch (error) {
logger.error(
`ERROR! Something when wrong when generating question! Error: ${err}`
);
return true;
}
}
);