# Daily Notification Plugin Migration Guide
**Author**: Matthew Raymer
**Version**: 2.0.0
**Created**: 2025-09-22 09:22:32 UTC
**Last Updated**: 2025-09-22 09:22:32 UTC
## Overview
This migration guide helps you transition from the basic daily notification plugin to the enhanced version with dual scheduling, callback support, and comprehensive observability.
## Breaking Changes
### API Changes
#### New Methods Added
- `scheduleContentFetch()` - Schedule content fetching separately
- `scheduleUserNotification()` - Schedule user notifications separately
- `scheduleDualNotification()` - Schedule both content fetch and notification
- `getDualScheduleStatus()` - Get comprehensive status information
- `registerCallback()` - Register callback functions
- `unregisterCallback()` - Remove callback functions
- `getRegisteredCallbacks()` - List registered callbacks
#### Enhanced Configuration
- New `DualScheduleConfiguration` interface
- Enhanced `NotificationOptions` with callback support
- New `ContentFetchConfig` and `UserNotificationConfig` interfaces
### Platform Requirements
#### Android
- **Minimum SDK**: API 21 (Android 5.0)
- **Target SDK**: API 34 (Android 14)
- **Permissions**: `POST_NOTIFICATIONS`, `SCHEDULE_EXACT_ALARM`, `USE_EXACT_ALARM`
- **Dependencies**: Room 2.6.1+, WorkManager 2.9.0+
#### iOS
- **Minimum Version**: iOS 13.0
- **Background Modes**: Background App Refresh, Background Processing
- **Permissions**: Notification permissions required
- **Dependencies**: Core Data, BGTaskScheduler
#### Web
- **Service Worker**: Required for background functionality
- **HTTPS**: Required for Service Worker and push notifications
- **Browser Support**: Chrome 40+, Firefox 44+, Safari 11.1+
## Migration Steps
### Step 1: Update Dependencies
```bash
npm install @timesafari/daily-notification-plugin@^2.0.0
```
### Step 2: Update Import Statements
```typescript
// Before
import { DailyNotification } from '@timesafari/daily-notification-plugin';
// After
import {
DailyNotification,
DualScheduleConfiguration,
ContentFetchConfig,
UserNotificationConfig,
CallbackEvent
} from '@timesafari/daily-notification-plugin';
```
### Step 3: Update Configuration
#### Basic Migration (Minimal Changes)
```typescript
// Before
await DailyNotification.scheduleDailyNotification({
title: 'Daily Update',
body: 'Your daily content is ready',
schedule: '0 9 * * *'
});
// After (backward compatible)
await DailyNotification.scheduleDailyNotification({
title: 'Daily Update',
body: 'Your daily content is ready',
schedule: '0 9 * * *'
});
```
#### Enhanced Migration (Recommended)
```typescript
// After (enhanced with dual scheduling)
const config: DualScheduleConfiguration = {
contentFetch: {
schedule: '0 8 * * *', // Fetch at 8 AM
ttlSeconds: 3600, // 1 hour TTL
source: 'api',
url: 'https://api.example.com/daily-content'
},
userNotification: {
schedule: '0 9 * * *', // Notify at 9 AM
title: 'Daily Update',
body: 'Your daily content is ready',
actions: [
{ id: 'view', title: 'View' },
{ id: 'dismiss', title: 'Dismiss' }
]
}
};
await DailyNotification.scheduleDualNotification(config);
```
### Step 4: Add Callback Support
```typescript
// Register callbacks for external integrations
await DailyNotification.registerCallback('analytics', {
kind: 'http',
target: 'https://analytics.example.com/events',
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json'
}
});
await DailyNotification.registerCallback('database', {
kind: 'local',
target: 'saveToDatabase'
});
// Local callback function
function saveToDatabase(event: CallbackEvent) {
console.log('Saving to database:', event);
// Your database save logic here
}
```
### Step 5: Update Status Monitoring
```typescript
// Before
const status = await DailyNotification.getNotificationStatus();
// After (enhanced status)
const status = await DailyNotification.getDualScheduleStatus();
console.log('Next runs:', status.nextRuns);
console.log('Cache age:', status.cacheAgeMs);
console.log('Circuit breakers:', status.circuitBreakers);
console.log('Performance:', status.performance);
```
## Platform-Specific Migration
### Android Migration
#### Update AndroidManifest.xml
```xml
```
#### Update build.gradle
```gradle
dependencies {
implementation "androidx.room:room-runtime:2.6.1"
implementation "androidx.work:work-runtime-ktx:2.9.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
annotationProcessor "androidx.room:room-compiler:2.6.1"
}
```
### iOS Migration
#### Update Info.plist
```xml
UIBackgroundModes
background-app-refresh
background-processing
BGTaskSchedulerPermittedIdentifiers
com.timesafari.dailynotification.content-fetch
com.timesafari.dailynotification.notification-delivery
```
#### Update Capabilities
1. Enable "Background Modes" capability
2. Enable "Background App Refresh"
3. Enable "Background Processing"
### Web Migration
#### Service Worker Registration
```typescript
// Register Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker registered:', registration);
})
.catch(error => {
console.error('Service Worker registration failed:', error);
});
}
```
#### Push Notification Setup
```typescript
// Request notification permission
const permission = await Notification.requestPermission();
if (permission === 'granted') {
// Subscribe to push notifications
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: 'your-vapid-public-key'
});
// Send subscription to your server
await fetch('/api/push-subscription', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(subscription)
});
}
```
## Testing Migration
### Unit Tests
```typescript
import { DailyNotification } from '@timesafari/daily-notification-plugin';
describe('Migration Tests', () => {
test('backward compatibility', async () => {
// Test that old API still works
await DailyNotification.scheduleDailyNotification({
title: 'Test',
body: 'Test body',
schedule: '0 9 * * *'
});
});
test('new dual scheduling', async () => {
const config = {
contentFetch: { schedule: '0 8 * * *', ttlSeconds: 3600 },
userNotification: { schedule: '0 9 * * *', title: 'Test' }
};
await DailyNotification.scheduleDualNotification(config);
const status = await DailyNotification.getDualScheduleStatus();
expect(status.nextRuns).toBeDefined();
});
test('callback registration', async () => {
await DailyNotification.registerCallback('test', {
kind: 'local',
target: 'testCallback'
});
const callbacks = await DailyNotification.getRegisteredCallbacks();
expect(callbacks).toContain('test');
});
});
```
### Integration Tests
```typescript
describe('Integration Tests', () => {
test('end-to-end dual scheduling', async () => {
// Schedule content fetch
await DailyNotification.scheduleContentFetch({
schedule: '0 8 * * *',
ttlSeconds: 3600,
source: 'api',
url: 'https://api.example.com/content'
});
// Schedule notification
await DailyNotification.scheduleUserNotification({
schedule: '0 9 * * *',
title: 'Daily Update',
body: 'Content ready'
});
// Verify status
const status = await DailyNotification.getDualScheduleStatus();
expect(status.nextRuns.length).toBe(2);
});
});
```
## Troubleshooting
### Common Issues
#### Android
- **Permission Denied**: Ensure all required permissions are declared
- **WorkManager Not Running**: Check battery optimization settings
- **Database Errors**: Verify Room database schema migration
#### iOS
- **Background Tasks Not Running**: Check Background App Refresh settings
- **Core Data Errors**: Verify Core Data model compatibility
- **Notification Permissions**: Request notification permissions
#### Web
- **Service Worker Not Registering**: Ensure HTTPS and proper file paths
- **Push Notifications Not Working**: Verify VAPID keys and server setup
- **IndexedDB Errors**: Check browser compatibility and storage quotas
### Debug Commands
```typescript
// Get comprehensive status
const status = await DailyNotification.getDualScheduleStatus();
console.log('Status:', status);
// Check registered callbacks
const callbacks = await DailyNotification.getRegisteredCallbacks();
console.log('Callbacks:', callbacks);
// Test callback firing
await DailyNotification.registerCallback('debug', {
kind: 'local',
target: 'debugCallback'
});
function debugCallback(event: CallbackEvent) {
console.log('Debug callback fired:', event);
}
```
## Performance Considerations
### Memory Usage
- **Android**: Room database with connection pooling
- **iOS**: Core Data with lightweight contexts
- **Web**: IndexedDB with efficient indexing
### Battery Optimization
- **Android**: WorkManager with battery-aware constraints
- **iOS**: BGTaskScheduler with system-managed execution
- **Web**: Service Worker with efficient background sync
### Network Usage
- **Circuit Breaker**: Prevents excessive retry attempts
- **TTL-at-Fire**: Reduces unnecessary network calls
- **Exponential Backoff**: Intelligent retry scheduling
## Security Considerations
### Permissions
- **Minimal Permissions**: Only request necessary permissions
- **Runtime Checks**: Verify permissions before operations
- **Graceful Degradation**: Handle permission denials gracefully
### Data Protection
- **Local Storage**: Encrypted local storage on all platforms
- **Network Security**: HTTPS-only for all network operations
- **Callback Security**: Validate callback URLs and headers
### Privacy
- **No Personal Data**: Plugin doesn't collect personal information
- **Local Processing**: All processing happens locally
- **User Control**: Users can disable notifications and callbacks
## Support
### Documentation
- **API Reference**: Complete TypeScript definitions
- **Examples**: Comprehensive usage examples
- **Troubleshooting**: Common issues and solutions
### Community
- **GitHub Issues**: Report bugs and request features
- **Discussions**: Ask questions and share solutions
- **Contributing**: Submit pull requests and improvements
### Enterprise Support
- **Custom Implementations**: Tailored solutions for enterprise needs
- **Integration Support**: Help with complex integrations
- **Performance Optimization**: Custom performance tuning
---
**Next Steps**: After migration, explore the [Enterprise Callback Examples](./enterprise-callback-examples.md) for advanced integration patterns.