diff --git a/.eslintrc b/.eslintrc index fae246d..3578cdd 100755 --- a/.eslintrc +++ b/.eslintrc @@ -52,7 +52,13 @@ "WithStatement", "BinaryExpression[operator=\"in\"]" ], - "arrow-parens": 0 + "arrow-parens": 0, + "import/no-unresolved": [ + "error", + { + "ignore": ["^firebase-admin/.+", "^firebase-functions/.+"] + } + ] }, "settings": { "react": { diff --git a/functions/index.js b/functions/index.js index 2637bde..a9b5893 100644 --- a/functions/index.js +++ b/functions/index.js @@ -1,74 +1,54 @@ -const functions = require('firebase-functions'); -const admin = require('firebase-admin'); -const express = require('express'); -const cors = require('cors')({ origin: true }); +const { onRequest } = require('firebase-functions/v2/https'); +const { initializeApp } = require('firebase-admin/app'); +const { getFirestore } = require('firebase-admin/firestore'); // Init Express App -const app = express(); -app.use(cors); +initializeApp(); +const db = getFirestore(); -admin.initializeApp(); - -exports.blog = functions.https.onRequest(app); - -const db = admin.firestore(); - -const blogCol = db.collection('blog'); -const increment = admin.firestore.FieldValue.increment(1); -const decrement = admin.firestore.FieldValue.increment(-1); - -function createNewDoc(blog) { +async function createNewDoc(blog) { db.collection('blog').doc(blog).set({ likes: 0 }); } -app.get('/:blog', (req, res) => { - const { blog } = req.params; - db.collection('blog') - .doc(blog) - .get() - .then((doc) => { - if (doc.exists) { - return res.status(200).json(doc.data()); - } - createNewDoc(blog); - return res.status(200).json({ likes: 0 }); - }) - .catch((error) => - res.status(500).json({ message: 'Error in GET /:blog', error }), - ); -}); - -app.put('/:blog', (req, res) => { - const { blog } = req.params; +exports.getBlog = onRequest(async (req, res) => { + const blog = req.params[0]; db.collection('blog') .doc(blog) .get() .then((doc) => { - if (doc.exists) { - blogCol.doc(blog).update({ likes: increment }); - return res.status(200).json({ success: true }); + if (!doc.exists) { + createNewDoc(blog); + return res.status(200).json({ success: true, likes: doc.data().likes }); } - createNewDoc(blog); - return res.status(200).json({ success: true }); + return res.status(200).json({ success: true, likes: doc.data().likes }); }) - .catch((error) => - res.status(500).json({ message: 'Error in PUT /:blog', error }), - ); + .catch((error) => { + return res.status(500).json({ + message: 'Error in blog onRequest /:blog', + error: error.message, + }); + }); }); -app.put('/:blog/unlike', (req, res) => { - const { blog } = req.params; +exports.likeBlog = onRequest(async (req, res) => { + const blog = req.params[0]; db.collection('blog') .doc(blog) .get() .then((doc) => { - if (doc.exists) { - blogCol.doc(blog).update({ likes: decrement }); - return res.status(200).json({ success: true }); + if (!doc.exists) { + createNewDoc(blog); + return res + .status(200) + .json({ success: true, likes: doc.data().likes + 1 }); } - return res.status(200).json({ success: true }); + doc.ref.update({ likes: doc.data().likes + 1 }); + return res.status(200).json({ success: true, likes: doc.data().likes }); }) - .catch((error) => - res.status(500).json({ message: 'Error in PUT /:blog/unlike', error }), - ); + .catch((error) => { + return res.status(500).json({ + message: 'Error in blog onRequest /:blog', + error: error.message, + }); + }); }); diff --git a/functions/package-lock.json b/functions/package-lock.json index 8d91ccf..787ebfc 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -7,15 +7,15 @@ "name": "functions", "dependencies": { "cors": "^2.8.5", - "express": "^4.17.1", + "express": "^4.18.3", "firebase-admin": "^12.0.0", - "firebase-functions": "^3.11.0" + "firebase-functions": "^4.8.0" }, "devDependencies": { "firebase-functions-test": "^0.2.0" }, "engines": { - "node": "14" + "node": "21" } }, "node_modules/@fastify/busboy": { @@ -222,32 +222,27 @@ "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "optional": true + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "optional": true + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "optional": true + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "optional": true + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "optional": true, "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -256,32 +251,27 @@ "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "optional": true + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "optional": true + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "optional": true + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "optional": true + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "optional": true + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@tootallnate/once": { "version": "2.0.0", @@ -1022,25 +1012,25 @@ } }, "node_modules/firebase-functions": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.24.1.tgz", - "integrity": "sha512-GYhoyOV0864HFMU1h/JNBXYNmDk2MlbvU7VO/5qliHX6u/6vhSjTJjlyCG4leDEI8ew8IvmkIC5QquQ1U8hAuA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-4.8.0.tgz", + "integrity": "sha512-8+Tgofl/w7reVVzJ1CSVPYwSRwmOMV8fACDdUkytoEP//wKb9olloMptKg2GahUbs6jHAIbT+B/jeMch4ouHQQ==", "dependencies": { "@types/cors": "^2.8.5", "@types/express": "4.17.3", "cors": "^2.8.5", "express": "^4.17.1", - "lodash": "^4.17.14", - "node-fetch": "^2.6.7" + "node-fetch": "^2.6.7", + "protobufjs": "^7.2.2" }, "bin": { "firebase-functions": "lib/bin/firebase-functions.js" }, "engines": { - "node": "^8.13.0 || >=10.10.0" + "node": ">=14.10.0" }, "peerDependencies": { - "firebase-admin": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0" + "firebase-admin": "^10.0.0 || ^11.0.0 || ^12.0.0" } }, "node_modules/firebase-functions-test": { @@ -1372,9 +1362,9 @@ } }, "node_modules/jose": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", - "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==", + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", "funding": { "url": "https://github.com/sponsors/panva" } @@ -1484,7 +1474,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.camelcase": { "version": "4.3.0", @@ -1535,8 +1526,7 @@ "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "optional": true + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/lru-cache": { "version": "4.0.2", @@ -1738,7 +1728,6 @@ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", "hasInstallScript": true, - "optional": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", diff --git a/functions/package.json b/functions/package.json index be70b3c..ef865e9 100644 --- a/functions/package.json +++ b/functions/package.json @@ -9,14 +9,14 @@ "logs": "firebase functions:log" }, "engines": { - "node": "14" + "node": "20" }, "main": "index.js", "dependencies": { "cors": "^2.8.5", - "express": "^4.17.1", + "express": "^4.18.3", "firebase-admin": "^12.0.0", - "firebase-functions": "^3.11.0" + "firebase-functions": "^4.8.0" }, "devDependencies": { "firebase-functions-test": "^0.2.0"