首页 > 解决方案 > 等待函数firebase函数

问题描述

我正在尝试在 firebase 函数中为 Google Cloud 任务创建函数。我得到日志:

1:01:36.743 AM
start
1:01:38.644 AM
Start google timer
1:01:38.653 AM
Final
1:01:38.767 AM
Function execution took 4341 ms, finished with status: 'ok'
1:02:04.541 AM
Error: 4 DEADLINE_EXCEEDED: Deadline exceeded at Object.callErrorFromStatus

我一直在寻找信息并猜测这是由于执行不正确的异步/等待请求造成的。我没有足够的知识来理解这一点。我需要如何正确执行异步请求?我的代码示例:

exports.newTimer = functions.database
    .instance("plan-b-b98f3-default-rtdb")
    .ref("{userUID}/timers/{keyID}")
    .onCreate(async (snapshot, context) => {
        const value = snapshot.val();
        await admin.database().ref(context.params.userUID + '/push').once('value',  (snapshotPush) => {
            functions.logger.info("start");
            return ScheduleRequest(value, snapshot.key).then(() => {
                functions.logger.info("success create cloud task", {structuredData: true});
            }).catch((e) => {
                functions.logger.error(e, {structuredData: true})
            });
        }, (errorObject) => {
            functions.logger.error('The read push tokens failed: ' + errorObject.name, {structuredData: true})
        });
        functions.logger.info("Final");
    });

const ScheduleRequest = async (timerKey, timer) => {
    const project = 'plan-b-b98f3';
    const location = 'us-central1';
    const queue = 'plnbtimers';
    const tasksClient = new CloudTasksClient();
    const queuePath = tasksClient.queuePath(project, location, queue);
    const url = `https://${location}-${project}.cloudfunctions.net/endTimerPush`;
    const json = {id: timerKey};

    functions.logger.info("Start google timer", {
        id: timerKey,
        total: timer.created + timer.duration
    });

    const task = {
        httpRequest: {
            httpMethod: 'POST',
            url,
            body: Buffer.from(JSON.stringify(json)).toString('base64'),
            headers: {
                'Content-Type': 'application/json',
            },
        },
        scheduleTime: {
            seconds: timer.created + timer.duration
        }
    }

    return await tasksClient.createTask({parent: queuePath, task});
};

标签: javascriptnode.jsfirebaseasync-awaitgoogle-cloud-functions

解决方案


Schedule Request函数对我来说看起来不错,但尝试newTimer像这样重构函数:

exports.newTimer = functions.database
    .instance("plan-b-b98f3-default-rtdb")
    .ref("{userUID}/timers/{keyID}")
    .onCreate(async (snapshot, context) => {
        try {
            const value = snapshot.val();
            const snapshotPush = await admin.database().ref(context.params.userUID + '/push').once('value')
            // if (!snapshot.val()) return false
            functions.logger.info("start");
            await ScheduleRequest(value, snapshot.key)
            functions.logger.info("success create cloud task", { structuredData: true });
            return null
        } catch (errorObject) {
            functions.logger.error('The read push tokens failed: ' + errorObject.name, { structuredData: true })
            functions.logger.info("Final");
            return null
        }
    });

你拿来snapshotPush干嘛?您是否只是检查该值是否存在?如果是,请取消注释返回 false 的行。

另一个重要的事情是您必须终止后台功能。注意return null语句。或者,您也可以像这样返回该承诺:

return ScheduleRequest(value, snapshot.key)

推荐阅读