Eggbeater is a tournament tracking tool for water polo teams and clubs. It does not sell or share personal data.
This Privacy Policy describes how the Eggbeater Water Polo app ("the App") handles information when you use it at eggbeater.app or via our native mobile applications for iOS and Android. By using the App you agree to this policy.
1 Information We Collect
Information you provide:
- Player roster entries (cap numbers, first and last names) you type into the Roster tab — stored only on your device.
- Game scores and statistics you enter during live scoring — stored only on your device.
- GroupMe Bot ID, if you choose to configure it — stored only on your device.
Information from Google (if you sign in with Google):
- Your Google account display name, email address, and profile photo — used solely to identify your session and display your first name in the App header. This information is never stored on our servers.
- A unique user ID (UID) issued by Firebase Authentication, used to associate your saved preferences with your account in Firestore.
- A Google OAuth access token granting access to Google Calendar — requested at sign-in time (alongside account authentication) so parents only see one Google consent screen. This token is held in memory only and is never written to a server or database.
Admin authentication (if you sign in via the admin panel):
- Admins sign in with Google via Firebase Authentication. A Firebase ID token (JWT) is sent with each API request to the server for cryptographic verification.
- Your Firebase UID is stored in a club-specific admin authorization list on Cloudflare KV and in the Firestore club document to determine admin access. Only UIDs explicitly added by an existing admin are granted access.
- Admin ID tokens are refreshed automatically every 50 minutes and are never stored persistently on the server.
Preferences stored in the cloud (if you sign in with Google):
- My Players — the player names and age groups you have bookmarked, stored in Google Firestore under a path accessible only to your authenticated account.
- Selected age groups & team preferences — which tournament age groups and A/B team squads you have chosen to follow, stored alongside My Players in Firestore.
Signing in is entirely optional. If you do not sign in, all preferences remain on your device only (localStorage) and cloud sync is not used.
Multi-club data scoping:
- The App supports multiple water polo clubs. All data — schedules, scores, rosters, tournament history, and admin access — is scoped to a specific club identifier. Data from one club is never accessible to or mixed with another club's data.
- The club you are viewing is determined by a
?join=URL parameter or your saved preference. No cross-club data is ever loaded or transmitted.
Google Calendar (if you connect calendar sync):
- The name and ID of the calendar you select for game sync. This is stored in your browser's localStorage to remember your calendar choice between sessions.
- Calendar sync uses the OAuth token obtained at sign-in (see above) — no additional sign-in is required to connect your calendar.
Push notification subscription data:
- If you enable push notifications, your device generates a push subscription token. On iOS (native app), this is an Apple Push Notification service (APNs) device token. On the web and Android, this is a Web Push subscription endpoint. These tokens are stored on our Cloudflare Worker infrastructure solely to deliver schedule-update, game reminder, and announcement notifications.
- Along with your push token, we store your selected age groups, notification preferences (e.g., game scores, schedule changes, reminders), and the date you subscribed. This data is used only to filter which notifications are relevant to you.
Club branding data:
- Club administrators may set custom branding colors (primary color, secondary color, header style) for their club. This data is stored on our Cloudflare Worker infrastructure and served publicly so all users of that club's app see the custom colors. Branding data contains no personal information.
Subscription and payment data (if you purchase a plan):
- Eggbeater offers optional paid plans for clubs (Club Plan) and parents (Parent Monthly) and for tournament hosting (Tournament Host). Payments are processed by RevenueCat (in-app purchases on iOS and Android via the App Store / Google Play) and Stripe (web checkout). We do not receive or store your credit card number, bank account, or payment card details — these are handled entirely by the payment processor.
- When you complete a purchase, RevenueCat or Stripe provides us with a subscription status (active, expired, trial) and entitlements linked to your account or club ID. This is used solely to unlock the features included in your plan.
- For club subscriptions managed through the admin panel, your club's Stripe customer ID is stored in Cloudflare KV to allow you to access the billing portal and manage your subscription.
- RevenueCat may collect anonymized analytics about purchase events. See RevenueCat's Privacy Policy for details. Stripe's data practices are governed by Stripe's Privacy Policy.
We do not collect your phone number, location, browsing history, or any other personally identifiable information beyond what is explicitly listed above.
2 How We Use Information
- Google Calendar access is used solely to create, update, and delete game events in the calendar you select. We do not read your existing calendar events, contacts, or any other Google data.
- Push subscription endpoints are used only to send you schedule-update notifications via the Web Push protocol. We do not use them for marketing or tracking.
- Google Sign-In is used only to authenticate your identity and enable cross-device preference sync. We do not access your emails, contacts, Drive, or any other Google services beyond authentication and calendar.
- Firestore preferences (My Players and selected age groups) are stored in Google Firestore and are readable and writable only by your authenticated account. This data is used solely to restore your settings when you sign in on a new device.
- On-device data (roster, scores, stats) stays on your device in your browser's localStorage and is never transmitted to our servers.
- Live score data entered by a designated scorer is temporarily stored (up to 8 hours) in Cloudflare KV to relay updates to other team members' devices. This data contains only game scores and statistics — no personal identifiers.
- Admin authentication tokens (Firebase ID tokens) are used solely to verify the admin's identity when making changes via the admin panel. Tokens are verified cryptographically using Google's public signing keys and are never stored on the server.
- Club-scoped data — all server-side data (schedules, rosters, scores, bot credentials) is stored in Cloudflare KV with a club-specific prefix. Tournament archives are stored in Firestore under a club-specific path. This ensures complete data isolation between clubs.
3 Google API Scopes & Firebase Authentication
Firebase Authentication (Google Sign-In): When you tap "Sign In," the App uses Firebase Authentication with Google's identity provider. This requests the standard OpenID Connect scopes (openid, email, profile) to authenticate your identity, plus the Google Calendar scope (see below) — all in a single consent screen. Firebase issues a UID stored in Firestore to associate your preferences with your account.
Google Calendar scope (bundled with sign-in): To eliminate friction, the App requests the following scope at the time of Google Sign-In, so parents only ever see one Google consent popup:
https://www.googleapis.com/auth/calendar— Required to create and manage game events in Google Calendar. This scope is only exercised when you explicitly connect a calendar in the Schedule tab.
On subsequent visits, if you have a calendar connected, the App silently refreshes the calendar access token in the background using Google Identity Services — no popup is shown.
The App's use of Google user data complies with the Google API Services User Data Policy, including the Limited Use requirements.
Google Calendar access tokens are held in memory only and are never written to a server, database, or persistent storage. They are discarded when you close the browser tab. Firebase Authentication tokens are managed by the Firebase SDK and are stored in your browser's local storage per Firebase's standard behavior.
Admin panel JWT verification: When an admin makes API requests, the Firebase ID token is sent as a Bearer token in the Authorization header. The server verifies this token using Google's public JSON Web Key Set (JWKS) endpoint — the token signature is checked cryptographically and the token's issuer, audience, and expiration are validated. The server never stores these tokens; they are verified and discarded on each request.
4 Data Sharing
We do not sell, trade, or share your personal information with third parties. The following third-party infrastructure is used to operate the App:
- Vercel — hosts the App's static files. Standard web access logs (IP address, browser type, pages visited) may be retained by Vercel per their own privacy policy.
- Cloudflare Workers / KV — processes push notification delivery, temporarily relays live score data, and stores club-scoped tournament data (schedules, rosters, scores, bot credentials). Admin Firebase UIDs are stored in KV for authorization checks. All data is namespaced by club ID to ensure complete isolation between clubs.
- Google Firebase (Firestore & Authentication) — if you sign in, Firebase Authentication manages your identity session and Google Firestore stores your My Players and age group preferences. Data is stored in Google's us-central region. Firebase is governed by Google's Firebase Terms of Service and Google's Privacy Policy.
- Google LLC — provides OAuth authentication and Calendar API services when you choose to enable calendar sync.
- Apple Inc. — provides the Apple Push Notification service (APNs) for native iOS notifications and processes in-app purchases on iOS via the App Store.
- Google LLC (Firebase Cloud Messaging) — provides push notification delivery for the native Android app and processes in-app purchases on Android via Google Play.
- RevenueCat Inc. — manages in-app subscription entitlements and purchase events for native iOS and Android apps. RevenueCat receives anonymized purchase data and subscription status; it does not receive your payment card details. Governed by RevenueCat's Privacy Policy.
- Stripe Inc. — processes web-based payments for club subscriptions and tournament host purchases. Stripe handles all payment card data; we never see or store card numbers. Governed by Stripe's Privacy Policy.
5 Data Retention & Deletion
- On-device data (roster, scores, history) can be cleared at any time by clearing your browser's site data or localStorage in your device settings.
- Firestore preferences (My Players, age groups) are retained until you request deletion. You can sign out at any time via the "Sign Out" button in the App header. To request deletion of your Firestore data, contact the App administrator.
- Firebase Authentication sessions are managed by Firebase. You can revoke your sign-in at any time by signing out in the App or by visiting your Google Account permissions page.
- Push subscriptions are removed from Cloudflare KV when you unsubscribe in the App, or automatically expire after 60 days of inactivity.
- Live score relay data in Cloudflare KV expires automatically after 8 hours.
- Google Calendar events created by the App can be deleted at any time by disconnecting calendar sync in the App or manually in Google Calendar.
- Admin authorization data (Firebase UIDs in KV and Firestore) is retained until removed by a club admin. Admins can add or remove authorized UIDs through the admin panel's Club Admins card.
- Tournament archives in Firestore are retained indefinitely under the club's document path. Club admins can delete archived tournaments through the admin panel's tournament selector.
6 Children's Privacy
The App is intended for use by parents, guardians, and coaches of team members. While the App tracks first and last names of players (who may be minors), this data is entered by parents or coaches, stored only on their own device, and never transmitted to or stored on our servers. We do not knowingly collect personal information from children.
7 Security
All communication between your device and our infrastructure is encrypted via HTTPS/TLS. Google OAuth tokens are never stored in cookies, databases, or any persistent server-side storage. On-device data in localStorage is protected by the same-origin policy of your browser.
Admin API requests are authenticated using Firebase ID tokens (JWTs) verified via RS256 signature validation against Google's public signing keys. Admin authorization is enforced at both the Cloudflare Worker level (KV-based UID check) and the Firestore level (security rules restricting writes to authorized UIDs). All club data is isolated by club-specific key prefixes in KV and document paths in Firestore — no cross-club data access is possible.
8 Changes to This Policy
If we make material changes to this Privacy Policy, the "Last updated" date at the top of this page will be revised. Continued use of the App after changes constitutes acceptance of the updated policy.
9 Contact
Questions about this Privacy Policy or requests regarding your data can be directed to the administrator of your team's Eggbeater deployment.