diff --git a/functions/index.js b/functions/index.js index 241532f..ff97443 100644 --- a/functions/index.js +++ b/functions/index.js @@ -18,7 +18,7 @@ const authenticator = (req, res, next) => { .verifyIdToken(reqToken) .then((user) => { if (user.uid === reqUid) { - console.log('Verified Token - UID - ', reqUid); + console.info('Verified Token - UID - ', reqUid); if (req.method === 'POST') { const bodydata = JSON.parse(req.body); bodydata.uid = user.uid; @@ -29,16 +29,55 @@ const authenticator = (req, res, next) => { } return next(); } else { - return res.status(401).send('Unauthorized'); + return res.status(401).send({ message: 'Unauthorized' }); } }) .catch((err) => { - console.log('Failed Auth - ', req.headers.authorization, '\n', err); - return res.status(500).send(err); + console.error('Failed Auth - ', req.headers.authorization, '\n', err); + return res.status(500).send({ message: 'Unable to verify user token', ...err }); }); return null; }; +const timeDiff = (ds1, ds2) => { + const d1 = new Date(ds1); + const d2 = new Date(ds2); + var diff = (d2.getTime() - d1.getTime()) / 1000; + diff /= 60 * 60; + return Math.abs(Math.round(diff)); +}; + +const cleanUpRoom = async (roomId) => { + await admin + .firestore() + .collection('rooms') + .doc(roomId) + .collection('messages') + .listDocuments() + .then((messages) => messages.forEach((message) => message.delete())) + .catch((err) => { + console.error(`Failed to run auto clean up (delete room messages) @ ${roomId}`, err); + }); + await admin + .firestore() + .collection('rooms') + .doc(roomId) + .collection('users') + .listDocuments() + .then((users) => users.forEach((user) => user.delete())) + .catch((err) => { + console.error(`Failed to run auto clean up (delete room users) @ ${roomId}`, err); + }); + await admin + .firestore() + .collection('rooms') + .doc(roomId) + .delete() + .catch((err) => { + console.error(`Failed to run auto clean up (delete room) @ ${roomId}`, err); + }); +}; + const createRoom = async (req, res) => { const bodydata = JSON.parse(req.body); console.log('Requested Create - UID - ', bodydata.uid); @@ -87,7 +126,7 @@ const createRoom = async (req, res) => { err ); }); - res.status(201).send({ roomId }); + res.status(201).send({ roomId, message: 'Started a party!' }); }; const joinRoom = async (req, res) => { @@ -98,7 +137,13 @@ const joinRoom = async (req, res) => { .collection('rooms') .doc(bodydata.roomId) .get() - .then((roomSnap) => [roomSnap.exists, roomSnap.exists ? roomSnap.data().player.source : '']); + .then((roomSnap) => [roomSnap.exists, roomSnap.exists ? roomSnap.data().player.source : '']) + .catch((err) => { + console.error( + `Failed to get room when joining room : \n\t Room: ${bodydata.roomId} \n\t User: ${bodydata.uid}`, + err + ); + }); const userExists = await admin .firestore() .collection('rooms') @@ -106,9 +151,15 @@ const joinRoom = async (req, res) => { .collection('users') .doc(bodydata.uid) .get() - .then((userSnap) => userSnap.exists); + .then((userSnap) => userSnap.exists) + .catch((err) => { + console.error( + `Failed to get user when joining room : \n\t Room: ${bodydata.roomId} \n\t User: ${bodydata.uid}`, + err + ); + }); if (userExists && exists && roomSource === bodydata.source) - res.status(200).send({ roomId: bodydata.roomId }); + res.status(200).send({ roomId: bodydata.roomId, message: 'Joined a party' }); else if ( !userExists && exists && @@ -162,7 +213,7 @@ const joinRoom = async (req, res) => { err ); }); - res.status(200).send({ roomId: bodydata.roomId }); + res.status(200).send({ roomId: bodydata.roomId, message: 'Joined a party' }); } else if (!userExists && !bodydata.userName) res.status(400).send({ message: 'Missing user name' }); else if (exists && roomSource !== bodydata.source) @@ -191,10 +242,23 @@ const sendMessage = async (req, res) => { time, uid, }) - .catch((messageErr) => res.status(500).send(messageErr)); - await admin.firestore().collection('rooms').doc(roomId).update({ - updatedAt: new Date().toISOString(), - }); + .catch((err) => { + console.error(`Failed to send message to party : \n\t Room: ${roomId} \n\t ${uid}`, err); + res.status(500).send({ message: "Couldn't send your message", ...messageErr }); + }); + await admin + .firestore() + .collection('rooms') + .doc(roomId) + .update({ + updatedAt: new Date().toISOString(), + }) + .catch((err) => { + console.error( + `Failed to set updated time when sending messasge to party : \n\t Room: ${roomId} \n\t User: ${uid}`, + err + ); + }); res.status(200).send({ message: 'Sent a message' }); } else { res.status(404).send({ message: 'Looks like this party is over' }); @@ -247,7 +311,12 @@ const deleteRoom = async (req, res) => { .collection('messages') .listDocuments() .then((messages) => messages.forEach((message) => message.delete())) - .catch((err) => res.status(500).send(err)); + .catch((err) => { + console.error( + `Failed to delete room messages : \n\t Room: ${req.params.rid} \n\t User: ${req.params.uid}`, + err + ); + }); await admin .firestore() .collection('rooms') @@ -255,13 +324,23 @@ const deleteRoom = async (req, res) => { .collection('users') .listDocuments() .then((users) => users.forEach((user) => user.delete())) - .catch((err) => res.status(500).send(err)); + .catch((err) => { + console.error( + `Failed to delete room users : \n\t Room: ${req.params.rid} \n\t User: ${req.params.uid}`, + err + ); + }); await admin .firestore() .collection('rooms') .doc(req.params.rid) .delete() - .catch((err) => res.status(500).send(err)); + .catch((err) => { + console.error( + `Failed to delete room : \n\t Room: ${req.params.rid} \n\t User: ${req.params.uid}`, + err + ); + }); res.status(200).send({ message: 'Ended the party' }); }; @@ -316,7 +395,10 @@ const updatePlayer = async (req, res) => { .update({ player, }) - .catch((err) => res.status(500).send(err)); + .catch((err) => { + console.error(`Failed to update player : \n\t Room: ${roomId} \n\t ${uid}`, err); + res.status(500).send({ message: "Uh oh party could't be synced", ...err }); + }); await admin .firestore() .collection('rooms') @@ -327,13 +409,19 @@ const updatePlayer = async (req, res) => { name: '', text: `${userName} ${statusString} ${timeString}`, time: new Date().toISOString(), + }) + .catch((err) => { + console.error( + `Failed to add system update player message : \n\t Room: ${roomId} \n\t ${uid}`, + err + ); }); return res.status(200).send({ message: 'Synced party player' }); } else { return res.status(208).send({ message: 'Player already up to date' }); } } else { - return res.status(401).send('Not in room to sync'); + return res.status(401).send({ message: 'Not in room to sync' }); } }; @@ -355,11 +443,37 @@ app.post('/updatePlayer', updatePlayer); exports.widgets = functions.https.onRequest(app); -exports.scheduledCleanUp = functions.pubsub.schedule('every 1 hour').onRun(async () => { - const roomsList = await admin +exports.scheduledCleanUp = functions.pubsub.schedule('every 60 minutes').onRun(async () => { + const startedTime = new Date().toISOString(); + const roomList = await admin .firestore() .collection('rooms') .listDocuments() - .then((rL) => rL.map(async (r) => await r.get())); - console.log(roomsList); + .then((rL) => rL) + .catch((err) => { + console.error( + `Failed to run auto clean up (get room list) @ ${new Date().toLocaleTimeString()}`, + err + ); + }); + roomList.forEach((roomRef) => { + roomRef + .get() + .then(async (roomSnap) => { + const roomData = roomSnap.data(); + if ( + timeDiff(roomData.createdAt, startedTime) >= 24 || + timeDiff(roomData.updatedAt, startedTime) >= 12 + ) + await cleanUpRoom(roomSnap.id); + console.info(`Deleted room ${roomSnap.id} from auto cleanup`); + return; + }) + .catch((err) => { + console.error( + `Failed to run auto clean up (get room snap) @ ${new Date().toLocaleTimeString()}`, + err + ); + }); + }); }); diff --git a/src/Chat.js b/src/Chat.js index bf78061..ba286fe 100644 --- a/src/Chat.js +++ b/src/Chat.js @@ -183,25 +183,29 @@ export default class Chat extends Component { const { admin, name, messages, newMessage } = this.state; return (