Using Frank's answer above, I was able to successfully utilize Cloud Tasks and Firebase Cloud Messaging to implement my feature! It's got a few kinks left to work out still, but I figured someone could use this later on if need be.
I mostly based my code from the suggested article
Here's the resulting code
cloud functions
const functions = require("firebase-functions");
const admin = require('firebase-admin')
const { CloudTasksClient } = require('@google-cloud/tasks');
admin.initializeApp()
exports.createTask = functions.https.onCall(async (data, context) => {
log("Create Task")
const taskClient = new CloudTasksClient();
let { time, uid, id } = data
// Get Date from time in format mm-dd-yyyy
let entryDate = new Date(time[0], time[1], time[2], time[3], time[4],);
const date = join(entryDate, '-');
let prevEntry = await admin.firestore().doc(`/users/${uid}/${date}/${id}`).get()
let prevEntryData = await prevEntry.data()
if (prevEntryData.hasOwnProperty('expirationTask')) {
// Delete old expiration task
await taskClient.deleteTask({ name: prevEntryData.expirationTask })
}
// This works now! Now I should create a task on google tasks
const todayDate = new Date()
const expirationAtSeconds = (entryDate.getTime() - new Date().getTime()) / 1000
const project = JSON.parse(process.env.FIREBASE_CONFIG).projectId
const location = 'us-central1'
const queue = 'firestore-ttl'
const queuePath = taskClient.queuePath(project, location, queue)
const url = `https://${location}-${project}.cloudfunctions.net/firestoreTtlCallback`
const docPath = `/users/${uid}/${date}/${id}`
const payload = {
docPath,
uid,
}
const task = {
httpRequest: {
httpMethod: 'POST',
url,
body: Buffer.from(JSON.stringify(payload)).toString('base64'),
headers: {
'Content-Type': 'application/json'
},
},
scheduleTime: {
seconds: expirationAtSeconds
}
}
const [response] = await taskClient.createTask({ parent: queuePath, task })
const expirationTask = response.name;
const update = { expirationTask }
// update the entry with the expiration task name
await admin.firestore().doc(docPath).update(update)
log("Done with Create Task")
return ['Success!']
})
// Callback to send message to users
exports.firestoreTtlCallback = functions.https.onRequest(async (req, res) => {
try {
const payload = req.body;
let entry = await (await admin.firestore().doc(payload.docPath).get()).data();
let tokens = await (await admin.firestore().doc(`/users/${payload.uid}`).get()).get('tokens')
// log(entry);
// log(tokens)
await admin.messaging().sendToDevice(
tokens,
{
data: {
title: JSON.stringify('App'),
body: JSON.stringify(entry['text'])
}
},
{
contentAvailable: true,
priority: 'high'
}
).then((response) => {
log('Successfully sent message:')
log(response)
admin.firestore().doc(payload.docPath).update({ expirationTask: admin.firestore.FieldValue.delete() })
}).catch((error) => {
log('Error in sending Message')
log(error)
})
res.status(200)
} catch (err) {
log(err)
res.status(500).send(err)
}
})