Skip to content

Push Notification for Next Day Training Sessions #5

@tristanblt

Description

@tristanblt

Description

Implement a scheduled push notification system that sends users a notification around 7 PM (19:00) each day to remind them about their training sessions scheduled for the next day. This helps athletes prepare and stay on track with their training plans.

Current State

  • Push notification infrastructure exists:
    • PushNotificationService (apps/api/src/modules/notification/services/push-notification.service.ts)
    • Firebase Functions for sending notifications (apps/firebase-functions/src/index.ts)
    • Push notification initialization in web app (apps/web/src/utils/push-notifications.ts)
  • Scheduled tasks are implemented using @nestjs/schedule:
    • MessageNotificationScheduler runs every minute
    • ProviderExportScheduler runs daily at 00:10 UTC
  • Events/Training sessions are stored in the Event and EventTraining models
  • Users have pushToken field in the User model

Requirements

Backend (NestJS API)

  1. Scheduled Notification Service

    • Create a new service: NextDaySessionNotificationScheduler
    • Schedule a cron job to run daily at 19:00 (7 PM) in user's local timezone
    • Note: Since users may be in different timezones, consider:
      • Running the job multiple times per day (e.g., every hour) and checking if it's 7 PM in the user's timezone
      • Or running at 7 PM UTC and allowing users to configure their preferred notification time
    • Query all users who have:
      • A valid pushToken
      • Training sessions (Event with type = TRAINING) scheduled for tomorrow
      • Notification preferences enabled (if we add this feature)
  2. Notification Content

    • Query tomorrow's training sessions for each user:
      // Pseudo-code
      const tomorrow = start of next day in user's timezone
      const sessions = await prisma.event.findMany({
        where: {
          athleteId: user.athleteId,
          type: 'TRAINING',
          startDate: {
            gte: tomorrow,
            lt: dayAfterTomorrow
          }
        },
        include: {
          training: {
            include: {
              sport: true
            }
          }
        }
      })
    • Generate notification message based on sessions:
      • Single session: "You have a [SPORT] training session tomorrow at [TIME]"
      • Multiple sessions: "You have [N] training sessions tomorrow"
      • Include session details (sport, time, name) if space allows
    • Support i18n (French and English based on user.language)
  3. Notification Service Integration

    • Use existing PushNotificationService.sendPushNotification() method
    • Batch notifications for efficiency
    • Handle errors gracefully (log failures, don't crash the scheduler)
  4. User Preferences (Optional but Recommended)

    • Add notification preferences to user settings:
      • Enable/disable next-day session notifications
      • Preferred notification time (default: 19:00)
      • Timezone preference
    • Database schema update:
      model User {
        // ... existing fields
        notificationPreferences Json? // Store preferences as JSON
        // Or create a separate NotificationPreferences model
      }
  5. Error Handling & Logging

    • Log successful notifications
    • Log failures with user ID and reason
    • Don't send duplicate notifications (track last notification sent)
    • Handle edge cases:
      • Users without push tokens
      • Users without athlete profiles
      • Sessions that were cancelled/deleted after notification was queued

Frontend (React/Web)

  1. Notification Preferences UI (Optional)

    • Add settings page/section for notification preferences
    • Allow users to:
      • Enable/disable next-day session notifications
      • Set preferred notification time
      • Set timezone
  2. Notification Handling (If needed)

    • Handle notification tap to navigate to calendar/day view
    • Deep linking to specific session (if supported)

Technical Implementation

Cron Schedule Options

Option 1: Run every hour, check timezone

@Cron('0 * * * *') // Every hour
async sendNextDayNotifications() {
  // Check if it's 7 PM in each user's timezone
  // Send notifications accordingly
}

Option 2: Run at 7 PM UTC, allow timezone preference

@Cron('0 19 * * *', { timeZone: 'UTC' }) // 7 PM UTC
async sendNextDayNotifications() {
  // Send to all users (they can set preferred time in settings)
}

Option 3: Multiple scheduled jobs for different timezones

  • More complex but more accurate
  • Run jobs at 7 PM for major timezones

Recommendation: Start with Option 2, add timezone support later

Notification Message Examples

English (single session):

Tomorrow's Training
You have a Running session at 8:00 AM

English (multiple sessions):

Tomorrow's Training
You have 3 training sessions scheduled

French (single session):

Entraînement de demain
Vous avez une séance de Course à 8h00

French (multiple sessions):

Entraînement de demain
Vous avez 3 séances d'entraînement prévues

Acceptance Criteria

  • Scheduled job runs daily at 7 PM (or configured time)
  • Notifications are sent to users with training sessions tomorrow
  • Notification content is accurate and includes session details
  • Notifications support both French and English
  • Users without push tokens are skipped gracefully
  • Errors are logged and don't crash the scheduler
  • No duplicate notifications are sent
  • Notification preferences are respected (if implemented)
  • Performance is acceptable (batch processing for many users)

Related Files

  • apps/api/src/modules/notification/services/push-notification.service.ts - Push notification service
  • apps/api/src/modules/notification/services/notification.service.ts - Notification service
  • apps/api/src/modules/messages/services/message-notification.scheduler.ts - Example scheduler implementation
  • apps/api/src/modules/providers-sync/scheduler.service.ts - Another scheduler example
  • apps/firebase-functions/src/index.ts - Firebase Functions for sending notifications
  • libs/database/prisma/schema/event.prisma - Event and EventTraining models
  • libs/database/prisma/schema/core.prisma - User model with pushToken

Future Enhancements

  • Allow users to customize notification time
  • Support for different notification types (competitions, notes)
  • Rich notifications with action buttons (e.g., "View Calendar", "Reschedule")
  • Notification history/log
  • Email fallback for users without push notifications enabled

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions