0

我编写了一个云任务,它运行良好,触发了我提供的链接,没有任何问题,但它不会停止重试运行链接。

我怎样才能让它只运行一次?

我正在尝试做的是在未来运行一次 Firestore 函数,在集合中写入的文档上。我找到了这个教程。

到目前为止,我的任务创建代码运行良好,并将正确的有效负载传递给它将调用的函数。并且被调用的函数在第一次运行并以状态 200 退出时也可以正常工作。但是在重试时,我必须以错误 500 退出,因为没有数据可以访问了。

我可以在 firestore 函数的日志中看到 200 和 500 日志,但 Cloud Tasks 的日志是空的,即使一个方法已经运行了 50 次!


这是完整的代码

import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'

const { CloudTasksClient } = require('@google-cloud/tasks')

exports.moveActivityFromPlanToRecord = () =>
    functions
    .region('europe-west1')
    .firestore.document('Users/{userId}/Activities/{activityId}')
        .onCreate(async snapshot => {

            const moveTime = snapshot.data()! as MoveTime

            if (!moveTime || !moveTime.dueTime) {
                console.log("DueTime is empty or null: \n" + moveTime)
                return
            }


            // Get the project ID from the FIREBASE_CONFIG env var
            const project = JSON.parse(process.env.FIREBASE_CONFIG!).projectId
            const location = 'europe-west1'
            const queue = 'activityDateEventChecker'

            //queuePath is going to be a string that uniquely identifes the task
            const tasksClient = new CloudTasksClient()
            const queuePath: string =
                tasksClient.queuePath(project, location, queue)

            // URL to my callback function and the contents of the payload to deliver
            const url = `https://${location}-${project}.cloudfunctions.net/activityDateEventCheckerCallback`
            const docPath = snapshot.ref.path
            const dueTime = moveTime.dueTime
            const payload: MoveTaskPayload = { docPath, dueTime }

            console.log(payload)

            // build up the configuration for the Cloud Task
            const task = {
                httpRequest: {
                    httpMethod: 'POST',
                    url: url,
                    body: Buffer.from(JSON.stringify(payload)).toString('base64'),
                    headers: {
                        'Content-Type': 'application/json',
                    },
                },
                scheduleTime: {
                    seconds: moveTime.dueTime / 1000
                }
            }

            // enqueue the task in the queue
            return tasksClient.createTask({ parent: queuePath, task: task })
        })


interface MoveTime extends admin.firestore.DocumentData {
    dueTime?: number
}
interface MoveTaskPayload {
    docPath: string,
    dueTime: number
}

exports.activityDateEventCheckerCallback = () =>
    functions
    .region('europe-west1')
    .https.onRequest(async (req, res) => {
        const payload = req.body as MoveTaskPayload
        try {
            // getting the item
            const activity = await admin.firestore().doc(payload.docPath).get()

            // if time is up for it
            if (Date.now() >= payload.dueTime && activity.data() != undefined) {
                // getting path to activity to be in record
                const pathUser = activity.ref.parent.parent?.path
                const pathDocRecord = admin.firestore().doc(`${pathUser}/Record/${activity.id}`)

                
                console.log("RECORD--  ", (await (await pathDocRecord.get()).data())?.subject)

                // moving activity into record
                await pathDocRecord.set(activity.data()!)
                await activity.ref.delete()


                // sending notif to user
                const fcmPayload = {
                    notification: {
                        title: `${activity.data()?.subject}`,
                        body: " Time for activity. Record how it goes!"
                    },
                    data: {
                        activityId: activity.id
                    }
                }

                const user = await admin.firestore().doc(pathUser!).get()
                const fcmToken: string = user.data()?.fcmToken

                return admin.messaging().sendToDevice(fcmToken, fcmPayload)
            }

            return null

        } catch (error) {
            console.error(error)
            res.status(500).send(error)
            return null
        }
    })
4

1 回答 1

1

Cloud Task 中的任务在未获得响应代码 2XX 时重试。

您可以使用 maxAttempt 参数在 Cloud Task Queue 中配置重试。

文档中提到了详细信息

于 2020-07-30T08:26:22.383 回答