You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
					
						
							12 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							12 KiB
						
					
					
				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 separatelyscheduleUserNotification()- Schedule user notifications separatelyscheduleDualNotification()- Schedule both content fetch and notificationgetDualScheduleStatus()- Get comprehensive status informationregisterCallback()- Register callback functionsunregisterCallback()- Remove callback functionsgetRegisteredCallbacks()- List registered callbacks
Enhanced Configuration
- New 
DualScheduleConfigurationinterface - Enhanced 
NotificationOptionswith callback support - New 
ContentFetchConfigandUserNotificationConfiginterfaces 
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
npm install @timesafari/daily-notification-plugin@^2.0.0
Step 2: Update Import Statements
// 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)
// 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)
// 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
// 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
// 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
<!-- Add new permissions -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Register new receivers -->
<receiver android:name="com.timesafari.dailynotification.NotifyReceiver"
          android:enabled="true"
          android:exported="false" />
<receiver android:name="com.timesafari.dailynotification.BootReceiver"
          android:enabled="true"
          android:exported="false">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
  </intent-filter>
</receiver>
Update build.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
<key>UIBackgroundModes</key>
<array>
    <string>background-app-refresh</string>
    <string>background-processing</string>
</array>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
    <string>com.timesafari.dailynotification.content-fetch</string>
    <string>com.timesafari.dailynotification.notification-delivery</string>
</array>
Update Capabilities
- Enable "Background Modes" capability
 - Enable "Background App Refresh"
 - Enable "Background Processing"
 
Web Migration
Service Worker Registration
// 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
// 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
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
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
// 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 for advanced integration patterns.