QFlowLearn: QTI 3.0 authoring
Implementing Cross-Platform Push Notifications in Sakai
July 10, 2025 Sakai

Implementing Cross-Platform Push Notifications in Sakai

Implementation notes for cross-platform Sakai push notifications, including iOS Safari Web Push requirements, VAPID setup, service workers, and delivery edge cases.

Implementing Cross-Platform Push Notifications in Sakai

Introduction

Push notifications help students and instructors keep up with coursework when they are not actively browsing the LMS. The hard part is platform behavior. iOS Safari, Android browsers, desktop Safari, Chrome, Firefox, and Edge do not all expose Web Push the same way.

This post covers the Sakai push notification changes for iOS Safari support, VAPID setup, subscription cleanup, and debugging.

The Challenge: iOS Safari and Web Push

When we began investigating push notifications for iOS Safari users, we expected to need Apple developer services and APNs certificates. iOS 16.4+ supports the Web Push Protocol in Progressive Web Apps (PWAs), using the same VAPID (Voluntary Application Server Identification) authentication as other browsers. Sakai does not need APNs certificates for this path.

Key Discovery: PWA Requirement

iOS Safari requires the site to be installed as a PWA before push notifications work. Android browsers and desktop Safari can receive push notifications directly in the browser.

Platform-Specific Implementation

iOS Safari PWA Requirements

  • iOS 16.4+ minimum version
  • PWA installation mandatory (add to home screen)
  • User interaction required for permission requests
  • Strict VAPID subject validation

Android Chrome/Firefox

  • No PWA required - works directly in browser
  • Background support for notifications
  • Firebase Cloud Messaging (FCM) backend integration

Desktop Browsers

  • Universal support across Chrome, Firefox, Safari, Edge
  • Standard Web Push Protocol implementation

Implementation Notes

1. VAPID Subject Configuration Issues

Apple’s push service returns 403 Forbidden for improperly formatted VAPID subjects.

Problem: Default configuration used empty string

# This caused 403 errors from Apple
portal.notifications.push.subject=""

Solution: Defaults with proper formatting

String defaultSubject = "https://" + serverConfigurationService.getServerName();
String pushSubject = serverConfigurationService.getString("portal.notifications.push.subject", defaultSubject);

Key Requirements for Apple:

  • No spaces after colons: mailto:admin@school.edu ✅ (not mailto: <admin@school.edu> ❌)
  • Valid HTTPS URLs or mailto addresses
  • Domain doesn’t need to match your Sakai instance

2. Browser Detection

Sakai needs platform-specific behavior, so the browser checks distinguish iOS Safari from other browsers and detect whether the app is running as a PWA:

export const isIOSSafari = () => {
  const ua = getUserAgent();
  return /iPad|iPhone|iPod/.test(ua) && /Safari/.test(ua) && !/Chrome/.test(ua);
};

export const isPWA = () => {
  const standaloneMode = window.matchMedia("(display-mode: standalone)").matches;
  const iosPWA = window.navigator.standalone === true;
  return standaloneMode || iosPWA;
};

3. User Experience Changes

iOS Safari Browser (Non-PWA):

  • Shows informational banner about PWA installation
  • Displays notifications immediately below (no button click required)
  • Provides clear installation instructions

iOS Safari PWA:

  • Full push notification support
  • Automatic permission flow after user interaction
  • Badge support for notification counts

4. Automatic Subscription Cleanup

Sakai removes failed push endpoints when the push service reports a permanent failure:

// Handle subscription cleanup for permanent failures
if (statusCode == 410 || statusCode == 404 || statusCode == 400) {
    log.info("Removing invalid push subscription for user {} due to status {}", 
            un.getToUser(), statusCode);
    clearUserPushSubscription(un.getToUser());
}

Status codes handled:

  • 410 Gone - Subscription expired (common with FCM)
  • 404 Not Found - Endpoint no longer valid
  • 400 Bad Request - Malformed subscription
  • 403 Forbidden - VAPID authentication issues (logged but not auto-deleted)

Debugging iOS Safari Push Notifications

Remote Debugging Setup

The key to debugging iOS Safari push notifications is using Safari’s remote debugging feature:

  1. Connect iOS device to Mac via USB
  2. Enable Web Inspector on iOS: Settings → Safari → Advanced → Web Inspector
  3. Open Safari on Mac → Develop menu → [Your Device] → [Your PWA]
  4. Access full console and network debugging tools

Debugging Points

Frontend Debugging:

console.debug("PWA detection:", { standaloneMode, iosPWA, isPwaMode });
console.debug("Push subscription created:", sub);
console.debug("Subscription endpoint:", sub.endpoint);

Backend Debugging:

log.info("Push service configured with VAPID subject: {}", pushSubject);
log.warn("Push notification to {} failed with status {} and reason {}", 
         pushEndpoint, statusCode, reason);

Things to monitor:

  • PWA detection accuracy
  • Push subscription creation success
  • Endpoint registration with backend
  • HTTP status codes from push services
  • VAPID subject configuration

Common Problems and Fixes

1. VAPID Subject Formatting

Problem: Spaces and brackets in mailto format Solution: Use exact format mailto:admin@school.edu

2. PWA Installation Detection

Problem: iOS standalone detection not working Solution: Check both CSS media query and navigator.standalone

3. Permission Timing

Problem: Requesting permissions too early Solution: Wait for user interaction and PWA installation

4. Subscription Endpoint Cleanup

Problem: Accumulating invalid endpoints causing errors Solution: Automatic cleanup based on HTTP status codes

Security Considerations

VAPID Authentication

  • Keys are not tied to domains - can use any valid URL/email as subject
  • No APNs certificates needed for iOS Web Push
  • Subject identifies the sender for push service rate limiting

Privacy

  • User consent required for all push notifications
  • Subscription data encrypted using Web Push Protocol
  • No personal data in push payloads - use notification IDs instead

Performance Work

Efficient Error Handling

// Only process users with complete subscription data
if (StringUtils.isAnyBlank(pushEndpoint, pushUserKey, pushAuth)) {
    log.debug("Skipping push notification due to missing subscription details");
    return;
}

Subscription Lifecycle Management

  • Automatic cleanup of invalid subscriptions
  • Fingerprint-based deduplication to prevent multiple subscriptions per device
  • User-based subscription lookup for efficient targeting

Documentation Updates

We enhanced Sakai’s default configuration documentation:

# Generate the key and pub using openssl
# openssl ecparam -name prime256v1 -genkey -noout -out sakai/sakai_push.key
# openssl ec -in sakai/sakai_push.key -pubout -out sakai/sakai_push.key.pub
#
# DEFAULT: the servername  
# IMPORTANT: Apple seems to want zero spaces or brackets
# portal.notifications.push.subject=mailto:somebody@sakai.edu

Results

Zero-Configuration Experience

With these changes, new Sakai installations work with less manual setup:

  • Automatic VAPID subject using server name
  • No manual configuration required for basic functionality
  • Platform detection for the right user flow

Cross-Platform Compatibility

  • iOS Safari PWA: Full push notification support
  • iOS Safari Browser: Graceful degradation with installation guidance
  • Android/Desktop: Existing functionality maintained
  • Automatic cleanup: Self-maintaining subscription database

Debugging

  • Useful logging for troubleshooting
  • Status code handling for all major push services
  • Clear error messages for configuration issues

Conclusion

Cross-platform push notifications depend on platform details. iOS Safari’s PWA requirement is the main difference: users must install the site before Sakai can ask for push permission.

Key takeaways for other developers:

  1. Test extensively on actual devices - simulators don’t always reflect real behavior
  2. Use remote debugging tools - they are necessary for iOS Safari development
  3. Handle error cases explicitly - push services fail in different ways
  4. Provide clear user guidance - PWA installation isn’t intuitive for all users
  5. Monitor and clean up subscriptions - invalid endpoints accumulate over time

The result is a push notification system that works across the major browser paths and gives iOS Safari users clear installation guidance.

For Sakai administrators, the changes reduce configuration work and push notification support requests. For users, they make notification behavior clearer on each platform.


This implementation is available in Sakai’s trunk branch under issue SAK-51709.

Related Articles

Work with Longsight

Bring us the problems that cross your LMS, identity, and compliance systems.

We can host the service, help you run it on campus, answer security review, integrate with your LMS, and work through accessibility requirements.