Sakai 25.0 Released!
Implementing Cross-Platform Push Notifications in Sakai
July 10, 2025 Sakai

Implementing Cross-Platform Push Notifications in Sakai

A Deep Dive into iOS Safari and Web Push

Implementing Cross-Platform Push Notifications in Sakai: A Deep Dive into iOS Safari and Web Push

Introduction

Push notifications have become an essential feature for modern learning management systems, keeping students and instructors connected to their coursework even when they’re not actively browsing the platform. However, implementing push notifications across different platforms, especially Apple’s iOS Safari, presents challenges that require careful attention.

In this post, we’ll walk through our journey of enhancing Sakai’s push notification system to support iOS Safari, the intricacies we discovered, the problems we solved, and the debugging techniques that made it work.

The Challenge: iOS Safari and Web Push

When we began investigating push notifications for iOS Safari users, we thought we’d need to subscribe to Apple’s developer services and manage APNs certificates. However, we discovered that iOS 16.4+ introduced support for the Web Push Protocol in Progressive Web Apps (PWAs), which uses the same VAPID (Voluntary Application Server Identification) authentication as other browsers, no APNs certificates required!

Key Discovery: PWA Requirement

The critical insight was that iOS Safari requires the site to be installed as a PWA before push notifications will work. This is different from Android browsers and desktop Safari, which 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

The Implementation Journey

1. VAPID Subject Configuration Issues

Our first major hurdle was Apple’s strict VAPID subject validation. We discovered that Apple’s push service returns 403 Forbidden for improperly formatted subjects.

Problem: Default configuration used empty string

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

Solution: Smart 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. Enhanced Browser Detection

We implemented comprehensive browser detection to provide platform-specific experiences:

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 Improvements

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

We implemented intelligent subscription management to handle failed push endpoints:

// 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

Essential 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);

Key things to monitor:

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

Common Pitfalls and Solutions

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 serves as identifier 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 Optimizations

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 Improvements

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 and Impact

Zero-Configuration Experience

With our improvements, new Sakai installations work out-of-the-box:

  • Automatic VAPID subject using server name
  • No manual configuration required for basic functionality
  • Smart platform detection for optimal user experience

Cross-Platform Compatibility

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

Enhanced Debugging

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

Conclusion

Implementing cross-platform push notifications revealed the importance of understanding each platform’s unique requirements. While iOS Safari’s PWA requirement initially seemed like a limitation, it actually provides a more integrated and powerful notification experience for users who choose to install the PWA.

Key takeaways for other developers:

  1. Test extensively on actual devices - simulators don’t always reflect real behavior
  2. Use remote debugging tools - essential for iOS Safari development
  3. Implement comprehensive error handling - push services fail in various 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 robust, self-maintaining push notification system that works seamlessly across all major platforms while providing clear guidance to users about the best experience available on their device.

For Sakai administrators, these improvements mean less configuration overhead and fewer support requests about push notifications. For users, it means a more reliable and intuitive notification experience regardless of their platform choice.


This implementation is available in Sakai’s trunk branch under issue SAK-51709, contributing to Sakai’s ongoing commitment to providing a modern, accessible learning experience across all devices and platforms.

Related Articles

Powering UI with Lit Web Components
Jan 10, 2025 Open Source

Powering UI with Lit Web Components

Discover how Sakai leverages Lit’s lightweight, standards-based web components to build a scalable, maintainable, and high-performance LMS interface for universities and enterprises.

Ready to transform your educational technology?

Whether you're a small school, an educational startup, or a large institution, our open-source solutions can be tailored to meet your specific needs and budget.