Skip to content

Commit

Permalink
Deploy Firestore indexes and security rules (#24)
Browse files Browse the repository at this point in the history
* Convert Emote.ticks to Emote.timestamp using Firestore Timestamp type.

* Add npm script to publish Firestore indexes and security rules.

* Clarify Firebase CLI usage and document how to deploy Firestore indexes/rules.
  • Loading branch information
mross-ua authored Oct 10, 2023
1 parent 1c69430 commit 18d0691
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 12 deletions.
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

Expand Down Expand Up @@ -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**<br>
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)
Expand Down
4 changes: 3 additions & 1 deletion db/Emotes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
CollectionReference,
DocumentData,

Timestamp,

query,
where,
orderBy,
Expand Down Expand Up @@ -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) {
Expand Down
17 changes: 16 additions & 1 deletion firestore.indexes.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
{
"indexes": [],
"indexes": [
{
"collectionGroup": "emotes",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "teamId",
"order": "ASCENDING"
},
{
"fieldPath": "timestamp",
"order": "ASCENDING"
}
]
}
],
"fieldOverrides": []
}
4 changes: 2 additions & 2 deletions firestore.rules
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
4 changes: 3 additions & 1 deletion pages/scoreboard/[[id]].vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script setup lang="ts">
import { Timestamp } from 'firebase/firestore';
import type { Team, Emote } from '~~/types';
import { useTeamStore } from '~~/stores/Team';
Expand Down Expand Up @@ -61,7 +63,7 @@ const fakeTeam = {
</div>

<ScoreboardEmojiBoard
@emote="addEmote({ teamId, emote: $event, ticks: Date.now() } as Emote)"
@emote="addEmote({ teamId, emote: $event, timestamp: Timestamp.now() } as Emote)"
:class="{ hidden: !route.params.id }"
class="px-4"
/>
Expand Down
3 changes: 2 additions & 1 deletion types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Timestamp } from 'firebase/firestore';
import { groupBy, keys } from 'lodash-es';

export type ID = string;
Expand Down Expand Up @@ -44,7 +45,7 @@ export interface Scoreboard {
export interface Emote {
teamId: ID,
emote: string,
ticks: number
timestamp: Timestamp
};

//TODO this can probably be refactored into something more readable
Expand Down

0 comments on commit 18d0691

Please sign in to comment.