Skip to content

A web application that sends daily sunrise notifications with weather conditions and a confidence score for optimal sunrise watching at Lamai Beach, Koh Samui, Thailand.

Notifications You must be signed in to change notification settings

alx/samui-sunrise

Repository files navigation

Samui Sunrise Alarm 🌅

A web application that sends daily sunrise notifications with weather conditions and a confidence score for optimal sunrise watching at Lamai Beach, Koh Samui, Thailand.

Features

  • Daily Notifications: Automated alerts at 4:45 AM Thailand time
  • Weather Integration: Real-time weather data from OpenWeatherMap API
  • Sunrise Scoring: Intelligent algorithm scoring sunrise quality (0-100) based on:
    • Cloud coverage (ideal: 20-40% for dramatic sunrises)
    • Visibility conditions
    • Weather patterns
  • Google Authentication: Simple sign-in with Google
  • Progressive Web App: Installable on mobile devices
  • Minimalist UI: Clean, focused user experience

Tech Stack

  • Frontend: Next.js 14 (React) + TypeScript
  • Backend: Firebase Cloud Functions (Node.js 20)
  • Database: Cloud Firestore
  • Authentication: Firebase Auth (Google provider)
  • Notifications: Firebase Cloud Messaging (FCM)
  • Hosting: Firebase Hosting
  • Weather API: OpenWeatherMap

Project Structure

sunrise_alarm/
├── functions/              # Firebase Cloud Functions
│   ├── src/
│   │   ├── index.ts       # Main entry point & scheduled function
│   │   ├── weather.ts     # Weather fetching & scoring logic
│   │   └── notifications.ts # FCM notification handling
│   └── package.json
├── frontend/              # Next.js web application
│   ├── app/
│   │   ├── page.tsx      # Main page component
│   │   ├── layout.tsx    # Root layout
│   │   └── globals.css   # Global styles
│   ├── lib/
│   │   ├── firebase.ts   # Firebase initialization
│   │   └── notifications.ts # FCM token management
│   └── public/           # Static assets
├── firebase.json         # Firebase configuration
├── firestore.rules       # Firestore security rules
└── package.json          # Root workspace config

Prerequisites

  • Node.js 20 or higher
  • npm or yarn
  • Firebase CLI (npm install -g firebase-tools)
  • Firebase project with Blaze (pay-as-you-go) plan for Cloud Functions
  • OpenWeatherMap API key (free tier available)

Setup Instructions

1. Firebase Project Setup

  1. Create a new Firebase project at Firebase Console

  2. Enable the following services:

    • Authentication: Enable Google sign-in provider
    • Firestore Database: Create in production mode
    • Cloud Functions: Upgrade to Blaze plan
    • Hosting: Enable Firebase Hosting
    • Cloud Messaging: Enable FCM
  3. Generate a web app configuration:

    • Go to Project Settings > General
    • Under "Your apps", click "Add app" and select Web
    • Register your app and copy the config object
  4. Generate VAPID key for FCM:

    • Go to Project Settings > Cloud Messaging
    • Under "Web Push certificates", click "Generate key pair"
    • Copy the key pair value

2. Get OpenWeatherMap API Key

  1. Sign up at OpenWeatherMap
  2. Subscribe to the free tier (60 calls/minute)
  3. Copy your API key from the API keys section

3. Local Environment Setup

  1. Clone and install dependencies:
git clone <your-repo-url>
cd sunrise_alarm
npm install
  1. Login to Firebase:
firebase login
firebase init

Select your Firebase project when prompted.

  1. Configure environment variables:

Frontend (frontend/.env.local):

cp frontend/.env.local.example frontend/.env.local

Edit frontend/.env.local with your Firebase config:

NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project-id.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project-id.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your-sender-id
NEXT_PUBLIC_FIREBASE_APP_ID=your-app-id
NEXT_PUBLIC_FIREBASE_VAPID_KEY=your-vapid-key

Functions (functions/.env):

cp functions/.env.example functions/.env

Edit functions/.env:

OPENWEATHER_API_KEY=your-openweather-api-key
LATITUDE=9.4631
LONGITUDE=100.0569
LOCATION_NAME=Lamai Beach, Koh Samui

Set Firebase Functions environment variables:

firebase functions:config:set \
  openweather.api_key="your-api-key" \
  location.latitude="9.4631" \
  location.longitude="100.0569" \
  location.name="Lamai Beach, Koh Samui"
  1. Update Service Worker config:

Edit frontend/public/firebase-messaging-sw.js with your Firebase config.

4. Deploy Firestore Security Rules

firebase deploy --only firestore:rules

5. Development

Run frontend locally:

cd frontend
npm run dev

Visit http://localhost:3000

Test Cloud Functions locally:

cd functions
npm run serve

Manual trigger for testing:

# After deploying functions
curl https://asia-southeast1-<your-project-id>.cloudfunctions.net/triggerSunriseNotification

6. Production Deployment

Deploy everything:

npm run deploy

Or deploy individually:

# Deploy functions only
firebase deploy --only functions

# Deploy frontend only
cd frontend && npm run build && cd ..
firebase deploy --only hosting

How It Works

Notification Flow

  1. Scheduled Trigger: Cloud Scheduler triggers the function daily at 4:45 AM Thailand time
  2. Weather Fetch: Function calls OpenWeatherMap API for current conditions
  3. Score Calculation: Algorithm evaluates:
    • Cloud coverage (20-40% is ideal for dramatic sunrises)
    • Visibility (higher is better)
    • Weather conditions (clear/cloudy preferred over rain)
  4. User Retrieval: Fetches all users with notifications enabled from Firestore
  5. Notification Dispatch: Sends FCM messages to all registered devices
  6. Token Cleanup: Removes invalid/expired FCM tokens

Sunrise Scoring Algorithm

The algorithm calculates a 0-100 score weighted as follows:

  • 50% Cloud coverage (ideal: 20-40% for colorful sunrises)
  • 30% Visibility conditions
  • 20% Weather type (clear/cloudy vs rain/fog)

Ratings:

  • Excellent (85-100): Perfect conditions
  • Good (70-84): Great viewing conditions
  • Fair (50-69): Decent sunrise possible
  • Poor (<50): Likely obscured

Firestore Data Structure

Users Collection

users/{userId}
  - fcmToken: string
  - notificationsEnabled: boolean
  - updatedAt: timestamp

Weather Collection (historical data)

weather/{documentId}
  - timestamp: timestamp
  - weather: {
      temperature: number,
      cloudCoverage: number,
      visibility: number,
      ...
    }
  - sunriseScore: {
      score: number,
      rating: string,
      factors: {...}
    }

Customization

Change Notification Time

Edit functions/src/index.ts:

.schedule("45 4 * * *") // Format: "minute hour * * *"
.timeZone("Asia/Bangkok")

Adjust Location

Edit functions/.env or Firebase Functions config:

LATITUDE=your-latitude
LONGITUDE=your-longitude
LOCATION_NAME=Your Location

Modify Scoring Algorithm

Edit functions/src/weather.ts in the calculateSunriseScore() function to adjust weights and thresholds.

Troubleshooting

Notifications Not Working

  1. Check browser notification permissions
  2. Verify VAPID key is correct in frontend config
  3. Check FCM token is saved in Firestore
  4. Verify service worker is registered (firebase-messaging-sw.js)
  5. Check Cloud Functions logs: firebase functions:log

Functions Deployment Fails

  1. Ensure Blaze plan is enabled
  2. Check Node.js version is 20
  3. Verify all environment variables are set
  4. Run cd functions && npm run build to check for TypeScript errors

Weather Data Not Updating

  1. Verify OpenWeatherMap API key is valid
  2. Check you haven't exceeded API rate limits (60 calls/min free tier)
  3. Review Cloud Functions logs for API errors

Cost Estimation

With typical usage (1-100 users):

  • Firebase Hosting: Free tier sufficient
  • Cloud Functions: ~$0.10/month (1 invocation/day)
  • Firestore: Free tier sufficient
  • FCM: Free (unlimited notifications)
  • OpenWeatherMap: Free tier (60 calls/min)

Total: Essentially free for small user base

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

License

MIT License - feel free to use this project for your own sunrise notifications!

Acknowledgments

  • Weather data provided by OpenWeatherMap
  • Built with Firebase
  • Designed for the beautiful sunrises at Lamai Beach, Koh Samui, Thailand

About

A web application that sends daily sunrise notifications with weather conditions and a confidence score for optimal sunrise watching at Lamai Beach, Koh Samui, Thailand.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •