A voting platform built with Svelte 3.
Features
- Dynamic Voting System: Admin can easily create and manage polls and votes
- Real-Time Updates: Instant feedback and live updates from voters
- Anonymous Voting: The votes cast are not stored in the database, only the counts
- Intuitive User Interface: Minimal and user-friendly design
- Backup Password Login (Add
?password
to the URL)
General Flow
- Voter input with their email address in the input
- The app will check if the email address is in the authorized email list
- A login link will be sent to their inbox
- Once the user logged in, they will be prompted to complete their profile
- The ballot will be displayed to the user when the admin choose to show it
[!WARNING]
This project is using an older version of Svelte and are not fully tested in the current state.
Setup
[!TIP]
Use us-central1
for the region in Firebase Functions to avoid CORS issues and get no-cost quota for Cloud Storage.
Initial Setup
- Clone the repository and install dependencies
- Create a Firebase project and change to Blaze pricing
- Initialize Authentication with Email/Password authentication with Passwordless sign-in
- Initialize Realtime Database
- In Realtime Database, copy the contents
database.rules.json
to the database rules
- Initialize Storage and set the rules to the following:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read: if request.auth != null;
allow write: if request.auth.token.admin;
}
}
}
- Setup a web app (Settings > General > Your apps) and copy the
firebaseConfig
at src/firebase.ts
Authorized Email
- Create a Google Sheets and list all authorized emails that can login in the first column (row-by-row)
- Go to "File" > "Share" > "Publish to the web"
- Select the sheet and change the type to "Comma-separated values (.csv)"
- Copy the link and paste it in
functions/src/index.ts
at AUTHORIZED_LIST
- In
setGlobalOptions
function, change the region
if different and maxInstances
or concurrency
if needed
- If needed, uncomment the line after
checkEmail
to check if the email contains the authorized domain
Deploy Functions
- Install Firebase CLI
- Run
firebase login
to login to your Firebase account (if not already)
- Run
firebase init functions
, select "Overwrite" > "TypeScript" > default for rest
- Run
firebase deploy --only functions
to deploy the functions
- In Firebase Console > Authentication, Go to Settings > Blocking functions (need to upgrade) and set to
blockUnauthorized
Set Admin
- Generate a service account key at: Firebase Admin SDK
- Copy the file to the root directory and rename it to
serviceAccountKey.json
- You can now set a user as admin by running
npx tsx setAdmin.ts add <email>
in the root directory, other commands include remove, check, and list
Pre-Deploy
- Modify the initial login text in
src/components/Login.svelte
(such as raising a ticket)
- Modify the title and footer in
src/routes/+page.svelte
- Modify the form input in
src/routes/profile/+page.svelte
Deployment
You may need to change the adapters if deployment fails.
See SvelteKit documentation for more information on deployment adapters.