diff --git a/README.md b/README.md index 347006e..5eca6d7 100644 --- a/README.md +++ b/README.md @@ -38,16 +38,16 @@ To install dependencies: npm install ``` -To install the Firebase CLI, [follow these instructions](https://www.npmjs.com/package/firebase-tools#installation) or simply run: +Google provides emulators of their cloud services for dev builds. You do not need a Firebase project to run the emulators. To install the Firebase CLI, [follow these instructions](https://www.npmjs.com/package/firebase-tools#installation) or simply run: ```bash npm install -g firebase-tools ``` -To start the Firestore emulator and run the Vite development server: +Then, to start the emulators and the app in dev mode: ```bash -firebase emulators:start +npm run firebase:emulators npm run dev ``` @@ -75,6 +75,20 @@ npm run preview Note that the preview feature may not work. A workaround is documented [here](https://github.com/nuxt/nuxt/issues/14454#issuecomment-1397357957) but it doesn't seem to help. +### Publish Firestore Indexes and Security Rules + +If the Firestore indexes or security rules have changed, they will need to be pushed during deployment of the app. + +Automating this is not so easy (see [#21](https://github.com/krazkidd/lineup/issues/21)), but it can be done through the Firebase CLI. + +```bash +firebase login +npm run firebase:deploy +``` + +> **Warning**
+By deploying the app and Firestore configuration separately, there is no way to avoid a race condition. Index builds are ["long-running operations"](https://firebase.google.com/docs/firestore/query-data/indexing#index_build_time) and security rules can take [several minutes to propagate](https://firebase.google.com/docs/rules/manage-deploy). + ## Hosting ### GitHub Pages (free) diff --git a/db/Emotes.ts b/db/Emotes.ts index 842dd27..6f67864 100644 --- a/db/Emotes.ts +++ b/db/Emotes.ts @@ -3,6 +3,8 @@ import { CollectionReference, DocumentData, + Timestamp, + query, where, orderBy, @@ -40,7 +42,7 @@ export function addEmote(emote: Emote) { } export function getRecentEmotes(teamId: ID) { - return query(_collRef, where("teamId", "==", teamId), where("ticks", ">", Date.now()), orderBy("ticks")); + return query(_collRef, where("teamId", "==", teamId), where("timestamp", ">", Timestamp.now()), orderBy("timestamp")); } export function subscribeToNewEmotes(teamId: ID, callbackFn: Function) { diff --git a/firestore.indexes.json b/firestore.indexes.json index 415027e..a74c51f 100644 --- a/firestore.indexes.json +++ b/firestore.indexes.json @@ -1,4 +1,19 @@ { - "indexes": [], + "indexes": [ + { + "collectionGroup": "emotes", + "queryScope": "COLLECTION", + "fields": [ + { + "fieldPath": "teamId", + "order": "ASCENDING" + }, + { + "fieldPath": "timestamp", + "order": "ASCENDING" + } + ] + } + ], "fieldOverrides": [] } diff --git a/firestore.rules b/firestore.rules index 9c37173..10d7255 100644 --- a/firestore.rules +++ b/firestore.rules @@ -33,12 +33,12 @@ service cloud.firestore { match /emotes/{id} { allow read; - // only allow writing Scoreboard type + // only allow writing Emote type allow write: if request.resource.data.size() == 3 && request.resource.data.teamId is string && request.resource.data.emote is string - && request.resource.data.ticks is int; + && request.resource.data.timestamp is timestamp; } // forbid everything else diff --git a/package-lock.json b/package-lock.json index 1e95176..31e816c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,8 @@ "nuxt": "^3.7.3", "pinia": "^2.1.6", "primeicons": "^6.0.1", - "primevue": "^3.33.0" + "primevue": "^3.33.0", + "prompts": "^2.4.2" }, "engines": { "node": "18.x", diff --git a/package.json b/package.json index d9a9f3c..e8241f6 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,11 @@ "scripts": { "build": "nuxt build", "build:digitalocean": "npm install --production=false && npm run build && npm ci", + "confirm": "node -e \"(async () => { process.exitCode = (await require('prompts').prompt({ type: 'confirm', message: 'Continue?', name: 'value' })).value ? 0 : 1; })()\"", + "firebase:emulators": "firebase emulators:start", + "prefirebase:deploy": "npm run confirm", + "firebase:deploy": "firebase deploy --only firestore", "dev": "nuxt dev", - "emulators": "firebase emulators:start", "generate": "nuxt generate", "preview": "nuxt preview", "postinstall": "nuxt prepare", @@ -28,7 +31,8 @@ "nuxt": "^3.7.3", "pinia": "^2.1.6", "primeicons": "^6.0.1", - "primevue": "^3.33.0" + "primevue": "^3.33.0", + "prompts": "^2.4.2" }, "dependencies": { "@firebase/app-types": "^0.9.0", diff --git a/pages/scoreboard/[[id]].vue b/pages/scoreboard/[[id]].vue index 31626b7..0c0f3a8 100644 --- a/pages/scoreboard/[[id]].vue +++ b/pages/scoreboard/[[id]].vue @@ -1,4 +1,6 @@