函数返回未定义、预期的 Promise 或值,并且无法使用云函数从 firebase 数据库中删除旧数据
Function returned undefined, expected Promise or value and unable to delete old data from firebase database using cloud functions
-
javascript
-
google-cloud-platform
-
firebase-realtime-database
-
google-cloud-functions
-
google-cloud-scheduler
我正在尝试删除数据库中超过 12 小时的多个节点。我正在使用 pub/sub 函数来触发此事件。我不知道我的代码是否真的循环遍历所有节点,因为我没有使用 onWrite
、onCreate
数据库触发器具体来说。这里是数据库的图像样本
这是pub/sub代码
exports.deletejob = functions.pubsub.topic('Oldtask').onPublish(() => {
deleteOldItem();
})
和 deleteOldItem 函数
function deleteOldItem(){
const CUT_OFF_TIME = 12 * 60 * 1000; // 12 Hours in milliseconds.
//var ref = admin.database().ref(`/articles/${id}`);
const ref = admin.database().ref(`/articles`);
const updates = {};
ref.orderByChild('id').limitToLast(100).on('value', function (response) {
var index = 0;
response.forEach(function (child) {
var element = child.val();
const datetime = element.timestamp;
const now = Date.now();
const cutoff = now - datetime;
if (CUT_OFF_TIME < cutoff){
updates[element.key] = null;
}
});
//This is supposed to be the returened promise
return ref.child(response.key).update(updates);
});
如果我做错了什么,我很想知道。 pub/sub 由已在 google 云调度程序
上设置的 JobScheduler 触发
您的代码中有几个问题给您带来麻烦。
- 承诺的处理不正确。特别是,您的顶级函数实际上从未 return 承诺过,它只是调用了
deleteOldItems()
.
- 您应该使用
once()
的承诺形式而不是使用回调调用 on()
因为在这种情况下您不想安装侦听器,您只需要一次结果,并且您想将其作为承诺链的一部分进行处理。
- 要删除节点,您应该在对该节点的引用上调用
remove()
。它还会生成一个承诺供您在此处使用。
- 您没有正确计算 12 小时的毫秒数,您计算的是 12 分钟的毫秒数:)
这是我想出的。它使用 http 函数而不是 pubsub 函数,并为我的测试添加了一条日志语句,但是您需要的修改应该是 trivial/obvious(只需更改原型并删除 deleteOldItems
之后的响应,但是请务必确保 returning deleteOldItems()
):
的结果
const functions = require('firebase-functions');
const admin = require('firebase-admin');
function deleteOldItems() {
const CUT_OFF_TIME = 12 * 60 * 60 * 1000; // 12 Hours in milliseconds.
const ref = admin.database().ref('/articles');
return ref.orderByChild('id').limitToLast(100).once('value')
.then((response) => {
const updatePromises = [];
const now = Date.now();
response.forEach((child) => {
const datetime = child.val().timestamp;
const cutoff = now - datetime;
console.log(`processing ${datetime} my cutoff is ${CUT_OFF_TIME} and ${cutoff}`);
if (CUT_OFF_TIME < cutoff){
updatePromises.push(child.ref.remove())
}
});
return Promise.all(updatePromises);
});
}
exports.doIt = functions.https.onRequest((request, response) => {
return deleteOldItems().then(() => { return response.send('ok') });
}
虽然我没有测试过它,但我很确定它可以包含在您对云调度程序的原始函数调用中:
exports.deletejob = functions.pubsub.topic('Oldtask').onPublish(() => {
return deleteOldItems();
})
当然,这仍然比您需要的要复杂,因为通过 id
订购并不能真正为您带来任何好处。相反,为什么不直接使用查询 return 截止时间之前最早的项目(例如,正是您要删除的项目)?我还切换到 limitToFirst
以确保 earliest 条目被丢弃,这看起来更自然并确保公平:
function deleteOldItems() {
const cutOffTime = Date.now() - (12 * 60 * 60 * 1000); // 12 Hours earlier in milliseconds.
const ref = admin.database().ref('/articles');
return ref.orderByChild('timestamp').endAt(cutOffTime).limitToFirst(100).once('value')
.then((response) => {
const updatePromises = [];
response.forEach((child) => {
updatePromises.push(child.ref.remove())
});
return Promise.all(updatePromises);
});
}
如果您对多个项目执行此操作,当然,您可能希望 add an index 时间戳字段以便范围查询更有效。
javascript
google-cloud-platform
firebase-realtime-database
google-cloud-functions
google-cloud-scheduler
我正在尝试删除数据库中超过 12 小时的多个节点。我正在使用 pub/sub 函数来触发此事件。我不知道我的代码是否真的循环遍历所有节点,因为我没有使用 onWrite
、onCreate
数据库触发器具体来说。这里是数据库的图像样本
这是pub/sub代码
exports.deletejob = functions.pubsub.topic('Oldtask').onPublish(() => {
deleteOldItem();
})
和 deleteOldItem 函数
function deleteOldItem(){
const CUT_OFF_TIME = 12 * 60 * 1000; // 12 Hours in milliseconds.
//var ref = admin.database().ref(`/articles/${id}`);
const ref = admin.database().ref(`/articles`);
const updates = {};
ref.orderByChild('id').limitToLast(100).on('value', function (response) {
var index = 0;
response.forEach(function (child) {
var element = child.val();
const datetime = element.timestamp;
const now = Date.now();
const cutoff = now - datetime;
if (CUT_OFF_TIME < cutoff){
updates[element.key] = null;
}
});
//This is supposed to be the returened promise
return ref.child(response.key).update(updates);
});
如果我做错了什么,我很想知道。 pub/sub 由已在 google 云调度程序
上设置的 JobScheduler 触发您的代码中有几个问题给您带来麻烦。
- 承诺的处理不正确。特别是,您的顶级函数实际上从未 return 承诺过,它只是调用了
deleteOldItems()
. - 您应该使用
once()
的承诺形式而不是使用回调调用on()
因为在这种情况下您不想安装侦听器,您只需要一次结果,并且您想将其作为承诺链的一部分进行处理。 - 要删除节点,您应该在对该节点的引用上调用
remove()
。它还会生成一个承诺供您在此处使用。 - 您没有正确计算 12 小时的毫秒数,您计算的是 12 分钟的毫秒数:)
这是我想出的。它使用 http 函数而不是 pubsub 函数,并为我的测试添加了一条日志语句,但是您需要的修改应该是 trivial/obvious(只需更改原型并删除 deleteOldItems
之后的响应,但是请务必确保 returning deleteOldItems()
):
const functions = require('firebase-functions');
const admin = require('firebase-admin');
function deleteOldItems() {
const CUT_OFF_TIME = 12 * 60 * 60 * 1000; // 12 Hours in milliseconds.
const ref = admin.database().ref('/articles');
return ref.orderByChild('id').limitToLast(100).once('value')
.then((response) => {
const updatePromises = [];
const now = Date.now();
response.forEach((child) => {
const datetime = child.val().timestamp;
const cutoff = now - datetime;
console.log(`processing ${datetime} my cutoff is ${CUT_OFF_TIME} and ${cutoff}`);
if (CUT_OFF_TIME < cutoff){
updatePromises.push(child.ref.remove())
}
});
return Promise.all(updatePromises);
});
}
exports.doIt = functions.https.onRequest((request, response) => {
return deleteOldItems().then(() => { return response.send('ok') });
}
虽然我没有测试过它,但我很确定它可以包含在您对云调度程序的原始函数调用中:
exports.deletejob = functions.pubsub.topic('Oldtask').onPublish(() => {
return deleteOldItems();
})
当然,这仍然比您需要的要复杂,因为通过 id
订购并不能真正为您带来任何好处。相反,为什么不直接使用查询 return 截止时间之前最早的项目(例如,正是您要删除的项目)?我还切换到 limitToFirst
以确保 earliest 条目被丢弃,这看起来更自然并确保公平:
function deleteOldItems() {
const cutOffTime = Date.now() - (12 * 60 * 60 * 1000); // 12 Hours earlier in milliseconds.
const ref = admin.database().ref('/articles');
return ref.orderByChild('timestamp').endAt(cutOffTime).limitToFirst(100).once('value')
.then((response) => {
const updatePromises = [];
response.forEach((child) => {
updatePromises.push(child.ref.remove())
});
return Promise.all(updatePromises);
});
}
如果您对多个项目执行此操作,当然,您可能希望 add an index 时间戳字段以便范围查询更有效。