Search code examples
firebasegoogle-cloud-firestoregoogle-cloud-functionscloudscheduled-tasks

Scheduling Daily Meetings with Cloud Functions


I am looking to build a web app that will schedule school classes so that when a class time starts, the function should wait 5 minutes and then check if he marked this meeting as finished; if not, we will send an email notifying the teacher that he/she missed a meeting.

My question is, how could I initiate a timer when the user adds a class meeting, and how could I make it repetitive so that it repeats daily simultaneously?

Note: I want this to be done with Cloud Functions. Also, I am using Firebase if that would make any difference


Solution

  • Instead of running a scheduled Cloud Functions at a given interval, I would advise you use the technique described in the following article for "scheduling a Cloud Function to run in the future with Cloud Tasks".

    This is particularly adapted to your case as explained in the article, because:

    • A scheduled function can only run as frequently as once per minute. This means that it might execute up to one minute later than you’d like, which might be an unacceptable delay.

    • You may be paying for useless, repeated function invocations and scheduler queries that might have no work to do.

    With the technique described in the article, you can, when you save a meeting, set the exact execution time of the Cloud Function that will verify if the 5 minutes delay is reached.

    If a meeting is canceled, just follow the section named "But what if I need to cancel the task?" in the article.


    For the repeating aspect (see my comment under your question) I would manage it in the meeting creation algorithm. If a meeting needs to be repeated, just create several instances of the same meeting with different time and date and manage the timer per instance.


    Update following your comment:

    For scheduling the execution for a given meeting, just calculate the time corresponding to <meeting time + 5 minutes>, express this time in epoch seconds and pass it to the configuration object used with Cloud Task.

    const task = {
        httpRequest: {
            httpMethod: 'POST',
            url,
            body: Buffer.from(JSON.stringify(payload)).toString('base64'),
            headers: {
                'Content-Type': 'application/json',
            },
        },
        scheduleTime: {
            seconds: ...  // Here your time in epoch seconds
            }
    }
    

    To check if the user attended the meeting, just implement the desired business logic in the HTTPS Cloud Function. Something along the following business logic:

    export const firestoreTtlCallback =
        functions.https.onRequest(async (req, res) => {
            const payload = req.body as ExpirationTaskPayload
            try {
                // Get the path of the meeting doc
                const meetingPath = payload.docPath
    
                // Check if the meeting doc is flagged as finished
                const meetingSnapshot = await admin.firestore().doc(payload.docPath).get();
                if (!meetingSnapshot.get('finished')) {   // If the field finished is not set to true
                    // Send an email
                    // I recommend to use the corresponding extension 
                    // See this article: https://medium.com/firebase-tips-tricks/how-to-send-e-mails-using-firebase-extensions-a10d7cd685c2
                }
    
                res.send(200)
            }
            catch (error) {
                console.error(error)
                res.status(500).send(error)
            }
        })