Integrate DailyNotificationPlugin with notification UI to enable native notifications on iOS/Android while maintaining web push for web/PWA. - Add platform detection to PushNotificationPermission component - Implement native notification flow via NotificationService - Hide push server setting on native platforms (not needed) - Add time conversion (AM/PM to 24-hour) for native plugin - Add comprehensive documentation Breaking Changes: None (backward compatible)
379 lines
12 KiB
Markdown
379 lines
12 KiB
Markdown
# Notification System Overview
|
|
|
|
**Date**: 2026-01-23
|
|
**Purpose**: Understanding notification architecture and implementation guide for daily-notification-plugin
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
Your app has **two separate notification systems** that coexist:
|
|
|
|
1. **Web Push Notifications** (Web/PWA platforms)
|
|
- Uses service workers, VAPID keys, and a push server
|
|
- Requires the "Notification Push Server" setting
|
|
- Server-based delivery
|
|
|
|
2. **Native Notifications** (iOS/Android via DailyNotificationPlugin)
|
|
- Uses native OS notification APIs
|
|
- On-device scheduling (no server needed)
|
|
- The "Notification Push Server" setting is **NOT used** for native
|
|
|
|
The system automatically selects the correct implementation based on platform using `Capacitor.isNativePlatform()`.
|
|
|
|
---
|
|
|
|
## Notification Push Server Setting
|
|
|
|
### Location
|
|
- **File**: `src/views/AccountViewView.vue` (lines 506-549)
|
|
- **UI Section**: Advanced Settings → "Notification Push Server"
|
|
- **Database Field**: `settings.webPushServer`
|
|
|
|
### Purpose
|
|
The "Notification Push Server" setting **ONLY applies to Web Push notifications** (web/PWA platforms). It configures:
|
|
|
|
1. **VAPID Key Retrieval**: The server URL used to fetch VAPID (Voluntary Application Server Identification) keys
|
|
2. **Subscription Endpoint**: Where push subscriptions are sent
|
|
3. **Push Message Delivery**: The server that sends push messages to browsers
|
|
|
|
### How It Works (Web Push Flow)
|
|
|
|
```
|
|
User enables notification
|
|
↓
|
|
PushNotificationPermission.vue opens
|
|
↓
|
|
Fetches VAPID key from: {webPushServer}/web-push/vapid
|
|
↓
|
|
Subscribes to browser push service
|
|
↓
|
|
Sends subscription + time + message to: {webPushServer}/web-push/subscribe
|
|
↓
|
|
Server stores subscription and schedules push messages
|
|
↓
|
|
Server sends push messages at scheduled time via browser push service
|
|
```
|
|
|
|
### Key Code Locations
|
|
|
|
**AccountViewView.vue** (lines 1473-1479):
|
|
```typescript
|
|
async onClickSavePushServer(): Promise<void> {
|
|
await this.$saveSettings({
|
|
webPushServer: this.webPushServerInput,
|
|
});
|
|
this.webPushServer = this.webPushServerInput;
|
|
this.notify.warning(ACCOUNT_VIEW_CONSTANTS.INFO.RELOAD_VAPID);
|
|
}
|
|
```
|
|
|
|
**PushNotificationPermission.vue** (lines 177-221):
|
|
- Retrieves `webPushServer` from settings
|
|
- Fetches VAPID key from `{webPushServer}/web-push/vapid`
|
|
- Uses VAPID key to subscribe to push notifications
|
|
|
|
**PushNotificationPermission.vue** (lines 556-575):
|
|
- Sends subscription to `/web-push/subscribe` endpoint (relative URL, handled by service worker)
|
|
|
|
### Important Notes
|
|
|
|
- ⚠️ **This setting is NOT used for native iOS/Android notifications**
|
|
- The setting defaults to `DEFAULT_PUSH_SERVER` if not configured
|
|
- Changing the server requires reloading VAPID keys (hence the warning message)
|
|
- Local development (`http://localhost`) skips VAPID key retrieval
|
|
|
|
---
|
|
|
|
## Daily Notification Plugin Integration
|
|
|
|
### Current Status
|
|
|
|
✅ **Infrastructure Complete**:
|
|
- Plugin registered (`src/plugins/DailyNotificationPlugin.ts`)
|
|
- Service abstraction layer created (`src/services/notifications/`)
|
|
- Platform detection working
|
|
- Native implementation ready (`NativeNotificationService.ts`)
|
|
|
|
🔄 **UI Integration Needed**:
|
|
- `PushNotificationPermission.vue` still uses web push logic
|
|
- AccountViewView notification toggles need platform detection
|
|
- Settings storage needs to handle both systems
|
|
|
|
### Architecture
|
|
|
|
```
|
|
NotificationService.getInstance()
|
|
↓
|
|
Platform Detection (Capacitor.isNativePlatform())
|
|
↓
|
|
┌─────────────────────┬─────────────────────┐
|
|
│ Native Platform │ Web Platform │
|
|
│ (iOS/Android) │ (Web/PWA) │
|
|
├─────────────────────┼─────────────────────┤
|
|
│ NativeNotification │ WebPushNotification │
|
|
│ Service │ Service │
|
|
│ │ │
|
|
│ Uses: │ Uses: │
|
|
│ - DailyNotification │ - Service Workers │
|
|
│ Plugin │ - VAPID Keys │
|
|
│ - Native OS APIs │ - Push Server │
|
|
│ - On-device alarms │ - Server scheduling │
|
|
└─────────────────────┴─────────────────────┘
|
|
```
|
|
|
|
### Key Differences
|
|
|
|
| Feature | Native (Plugin) | Web Push |
|
|
|---------|----------------|----------|
|
|
| **Server Required** | ❌ No | ✅ Yes (Notification Push Server) |
|
|
| **Scheduling** | On-device | Server-side |
|
|
| **Offline Delivery** | ✅ Yes | ❌ No (requires network) |
|
|
| **Background Support** | ✅ Full | ⚠️ Limited (browser-dependent) |
|
|
| **Permission Model** | OS-level | Browser-level |
|
|
| **Settings Storage** | Local only | Local + server subscription |
|
|
|
|
---
|
|
|
|
## Implementation Recommendations
|
|
|
|
### 1. Update PushNotificationPermission Component
|
|
|
|
**Current State**: Only handles web push
|
|
|
|
**Recommended Changes**:
|
|
|
|
```typescript
|
|
// In PushNotificationPermission.vue
|
|
import { NotificationService } from '@/services/notifications';
|
|
import { Capacitor } from '@capacitor/core';
|
|
|
|
async open(pushType: string, callback?: ...) {
|
|
const isNative = Capacitor.isNativePlatform();
|
|
|
|
if (isNative) {
|
|
// Use native notification service
|
|
const service = NotificationService.getInstance();
|
|
const granted = await service.requestPermissions();
|
|
|
|
if (granted) {
|
|
// Show time picker UI
|
|
// Then schedule via service.scheduleDailyNotification()
|
|
}
|
|
} else {
|
|
// Existing web push logic
|
|
// ... current implementation ...
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. Update AccountViewView Notification Toggles
|
|
|
|
**Current State**: Always uses `PushNotificationPermission` component (web push)
|
|
|
|
**Recommended Changes**:
|
|
|
|
```typescript
|
|
// In AccountViewView.vue
|
|
import { NotificationService } from '@/services/notifications';
|
|
import { Capacitor } from '@capacitor/core';
|
|
|
|
async showNewActivityNotificationChoice(): Promise<void> {
|
|
const isNative = Capacitor.isNativePlatform();
|
|
|
|
if (isNative) {
|
|
// Use native service directly
|
|
const service = NotificationService.getInstance();
|
|
// Show time picker, then schedule
|
|
} else {
|
|
// Use existing PushNotificationPermission component
|
|
(this.$refs.pushNotificationPermission as PushNotificationPermission)
|
|
.open(DAILY_CHECK_TITLE, ...);
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Settings Storage Strategy
|
|
|
|
**Current Settings Fields** (from `src/db/tables/settings.ts`):
|
|
- `notifyingNewActivityTime` - Time string for daily check
|
|
- `notifyingReminderTime` - Time string for reminder
|
|
- `notifyingReminderMessage` - Reminder message text
|
|
- `webPushServer` - Push server URL (web only)
|
|
|
|
**Recommendation**: These settings work for both systems:
|
|
- ✅ `notifyingNewActivityTime` - Works for both (native stores locally, web sends to server)
|
|
- ✅ `notifyingReminderTime` - Works for both
|
|
- ✅ `notifyingReminderMessage` - Works for both
|
|
- ⚠️ `webPushServer` - Only used for web push (hide on native platforms)
|
|
|
|
### 4. Platform-Aware UI
|
|
|
|
**Recommendations**:
|
|
|
|
1. **Hide "Notification Push Server" setting on native platforms**:
|
|
```vue
|
|
<h2 v-if="!isNativePlatform" class="text-slate-500 text-sm font-bold mb-2">
|
|
Notification Push Server
|
|
</h2>
|
|
```
|
|
|
|
2. **Update help text** to explain platform differences
|
|
|
|
3. **Show different messaging** based on platform:
|
|
- Native: "Notifications are scheduled on your device"
|
|
- Web: "Notifications are sent via push server"
|
|
|
|
---
|
|
|
|
## Notification Types
|
|
|
|
Your app supports two notification types:
|
|
|
|
### 1. Daily Check (`DAILY_CHECK_TITLE`)
|
|
- **Purpose**: Notify user of new activity/updates
|
|
- **Message**: Auto-generated by server (web) or app (native)
|
|
- **Settings Field**: `notifyingNewActivityTime`
|
|
|
|
### 2. Direct Push (`DIRECT_PUSH_TITLE`)
|
|
- **Purpose**: Daily reminder with custom message
|
|
- **Message**: User-provided (max 100 characters)
|
|
- **Settings Fields**: `notifyingReminderTime`, `notifyingReminderMessage`
|
|
|
|
Both types can be enabled simultaneously.
|
|
|
|
---
|
|
|
|
## Code Flow Examples
|
|
|
|
### Native Notification Flow (Recommended Implementation)
|
|
|
|
```typescript
|
|
// 1. Get service instance
|
|
const service = NotificationService.getInstance();
|
|
|
|
// 2. Request permissions
|
|
const granted = await service.requestPermissions();
|
|
if (!granted) {
|
|
// Show error, guide to settings
|
|
return;
|
|
}
|
|
|
|
// 3. Schedule notification
|
|
await service.scheduleDailyNotification({
|
|
time: '09:00', // HH:mm format (24-hour)
|
|
title: 'Daily Check-In',
|
|
body: 'Time to check your TimeSafari activity',
|
|
priority: 'normal'
|
|
});
|
|
|
|
// 4. Save to settings
|
|
await this.$saveSettings({
|
|
notifyingNewActivityTime: '09:00'
|
|
});
|
|
|
|
// 5. Check status
|
|
const status = await service.getStatus();
|
|
console.log('Enabled:', status.enabled);
|
|
console.log('Time:', status.scheduledTime);
|
|
```
|
|
|
|
### Web Push Flow (Current Implementation)
|
|
|
|
```typescript
|
|
// 1. Open PushNotificationPermission component
|
|
(this.$refs.pushNotificationPermission as PushNotificationPermission)
|
|
.open(DAILY_CHECK_TITLE, async (success, timeText) => {
|
|
if (success) {
|
|
// Component handles:
|
|
// - VAPID key retrieval from webPushServer
|
|
// - Service worker subscription
|
|
// - Sending subscription to server
|
|
|
|
// Just save the time
|
|
await this.$saveSettings({
|
|
notifyingNewActivityTime: timeText
|
|
});
|
|
}
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Testing Checklist
|
|
|
|
### Native (iOS/Android)
|
|
- [ ] Request permissions works
|
|
- [ ] Notification appears at scheduled time
|
|
- [ ] Notification survives app close
|
|
- [ ] Notification survives device reboot
|
|
- [ ] Both notification types can be enabled
|
|
- [ ] Cancellation works correctly
|
|
|
|
### Web Push
|
|
- [ ] VAPID key retrieval works
|
|
- [ ] Service worker subscription works
|
|
- [ ] Subscription sent to server
|
|
- [ ] Push messages received at scheduled time
|
|
- [ ] Works with different push server URLs
|
|
|
|
### Platform Detection
|
|
- [ ] Correct service selected on iOS
|
|
- [ ] Correct service selected on Android
|
|
- [ ] Correct service selected on web
|
|
- [ ] Settings UI shows/hides appropriately
|
|
|
|
---
|
|
|
|
## Key Files Reference
|
|
|
|
### Core Notification Services
|
|
- `src/services/notifications/NotificationService.ts` - Factory/selector
|
|
- `src/services/notifications/NativeNotificationService.ts` - Native implementation
|
|
- `src/services/notifications/WebPushNotificationService.ts` - Web implementation (stub)
|
|
|
|
### UI Components
|
|
- `src/components/PushNotificationPermission.vue` - Web push UI (needs update)
|
|
- `src/views/AccountViewView.vue` - Settings UI (lines 506-549 for push server)
|
|
|
|
### Settings & Constants
|
|
- `src/db/tables/settings.ts` - Settings schema
|
|
- `src/constants/app.ts` - `DEFAULT_PUSH_SERVER` constant
|
|
- `src/libs/util.ts` - `DAILY_CHECK_TITLE`, `DIRECT_PUSH_TITLE`
|
|
|
|
### Plugin
|
|
- `src/plugins/DailyNotificationPlugin.ts` - Plugin registration
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. **Update `PushNotificationPermission.vue`** to detect platform and use appropriate service
|
|
2. **Update `AccountViewView.vue`** notification toggles to use platform detection
|
|
3. **Hide "Notification Push Server" setting** on native platforms
|
|
4. **Test on real devices** (iOS and Android)
|
|
5. **Update documentation** with platform-specific instructions
|
|
|
|
---
|
|
|
|
## Questions & Answers
|
|
|
|
**Q: Do I need to configure the Notification Push Server for native apps?**
|
|
A: No. The setting is only for web push. Native notifications are scheduled on-device.
|
|
|
|
**Q: Can both notification systems be active at the same time?**
|
|
A: No, they're mutually exclusive per platform. The app automatically selects the correct one.
|
|
|
|
**Q: How do I test native notifications?**
|
|
A: Use `NotificationService.getInstance()` and test on a real device (simulators have limitations).
|
|
|
|
**Q: What happens if I change the push server URL?**
|
|
A: Only affects web push. Users need to re-subscribe to push notifications with the new server.
|
|
|
|
**Q: Can I use the same settings fields for both systems?**
|
|
A: Yes! The time and message fields work for both. Only `webPushServer` is web-specific.
|
|
|
|
---
|
|
|
|
**Last Updated**: 2026-01-23
|