Files
digital-pilates/docs/notification-implementation.md
richarjiang 7d28b79d86 feat: 集成推送通知功能及相关组件
- 在项目中引入expo-notifications库,支持本地推送通知功能
- 实现通知权限管理,用户可选择开启或关闭通知
- 新增通知发送、定时通知和重复通知功能
- 更新个人页面,集成通知开关和权限请求逻辑
- 编写推送通知功能实现文档,详细描述功能和使用方法
- 优化心情日历页面,确保数据实时刷新
2025-08-22 22:00:05 +08:00

7.2 KiB
Raw Permalink Blame History

推送通知功能实现文档

概述

本项目已成功集成本地推送通知功能,使用 Expo 官方的 expo-notifications 库。该功能支持立即通知、定时通知、重复通知等多种类型,并提供了完整的权限管理和通知处理机制。

技术栈

  • expo-notifications: Expo 官方推送通知库
  • React Native: 跨平台移动应用框架
  • TypeScript: 类型安全的 JavaScript 超集

文件结构

services/
├── notifications.ts          # 推送通知服务核心逻辑
hooks/
├── useNotifications.ts       # 推送通知自定义 Hook
components/
├── NotificationTest.tsx      # 通知功能测试组件
app/(tabs)/
├── personal.tsx             # 个人页面(集成通知开关)

核心功能

1. 通知服务 (services/notifications.ts)

主要特性

  • 单例模式: 确保全局只有一个通知服务实例
  • 权限管理: 自动请求和管理通知权限
  • 多种通知类型: 支持立即、定时、重复通知
  • 通知监听: 处理通知接收和点击事件
  • 便捷方法: 提供常用通知类型的快捷发送方法

核心方法

// 初始化通知服务
await notificationService.initialize();

// 发送立即通知
await notificationService.sendImmediateNotification({
  title: '标题',
  body: '内容',
  sound: true,
  priority: 'high'
});

// 安排定时通知
await notificationService.scheduleNotificationAtDate(
  notification,
  new Date(Date.now() + 5000) // 5秒后
);

// 安排重复通知
await notificationService.scheduleRepeatingNotification(
  notification,
  { minutes: 1 } // 每分钟重复
);

// 取消通知
await notificationService.cancelNotification(notificationId);
await notificationService.cancelAllNotifications();

2. 自定义 Hook (hooks/useNotifications.ts)

主要特性

  • 状态管理: 管理通知权限和初始化状态
  • 自动初始化: 组件挂载时自动初始化通知服务
  • 便捷接口: 提供简化的通知操作方法
  • 类型安全: 完整的 TypeScript 类型定义

使用示例

const {
  isInitialized,
  permissionStatus,
  sendNotification,
  scheduleNotification,
  sendWorkoutReminder,
  sendGoalAchievement,
} = useNotifications();

// 发送运动提醒
await sendWorkoutReminder('运动提醒', '该开始今天的普拉提训练了!');

// 发送目标达成通知
await sendGoalAchievement('目标达成', '恭喜您完成了本周的运动目标!');

3. 测试组件 (components/NotificationTest.tsx)

功能特性

  • 完整测试: 测试所有通知功能
  • 状态显示: 显示初始化状态和权限状态
  • 交互测试: 提供各种通知类型的测试按钮
  • 通知列表: 显示已安排的通知列表

配置说明

app.json 配置

{
  "expo": {
    "plugins": [
      [
        "expo-notifications",
        {
          "icon": "./assets/images/Sealife.jpeg",
          "color": "#ffffff",
          "sounds": ["./assets/sounds/notification.wav"]
        }
      ]
    ],
    "ios": {
      "infoPlist": {
        "UIBackgroundModes": ["remote-notification"]
      }
    },
    "android": {
      "permissions": [
        "android.permission.RECEIVE_BOOT_COMPLETED",
        "android.permission.VIBRATE",
        "android.permission.WAKE_LOCK"
      ]
    }
  }
}

使用场景

1. 运动提醒

// 每天定时发送运动提醒
await scheduleRepeatingNotification(
  {
    title: '运动提醒',
    body: '该开始今天的普拉提训练了!',
    data: { type: 'workout_reminder' },
    sound: true,
    priority: 'high'
  },
  { days: 1 }
);

2. 目标达成通知

// 用户达成目标时立即发送通知
await sendGoalAchievement('目标达成', '恭喜您完成了本周的运动目标!');

3. 心情打卡提醒

// 每天晚上提醒用户记录心情
const eveningTime = new Date();
eveningTime.setHours(20, 0, 0, 0);

await scheduleNotification(
  {
    title: '心情打卡',
    body: '记得记录今天的心情状态哦',
    data: { type: 'mood_checkin' },
    sound: true,
    priority: 'normal'
  },
  eveningTime
);

4. 营养提醒

// 定时提醒用户记录饮食
await scheduleRepeatingNotification(
  {
    title: '营养记录',
    body: '记得记录今天的饮食情况',
    data: { type: 'nutrition_reminder' },
    sound: true,
    priority: 'normal'
  },
  { hours: 4 } // 每4小时提醒一次
);

权限处理

iOS 权限

  • 自动请求通知权限
  • 支持后台通知模式
  • 处理权限被拒绝的情况

Android 权限

  • 自动请求必要权限
  • 支持开机启动和唤醒锁
  • 处理权限被拒绝的情况

通知处理

通知接收处理

Notifications.addNotificationReceivedListener((notification) => {
  console.log('收到通知:', notification);
  // 可以在这里处理通知接收逻辑
});

通知点击处理

Notifications.addNotificationResponseReceivedListener((response) => {
  const { notification } = response;
  const data = notification.request.content.data;
  
  // 根据通知类型处理不同的逻辑
  if (data?.type === 'workout_reminder') {
    // 跳转到运动页面
  } else if (data?.type === 'goal_achievement') {
    // 跳转到目标页面
  }
});

最佳实践

1. 通知内容

  • 标题简洁明了不超过50个字符
  • 内容具体有用不超过200个字符
  • 使用适当的优先级和声音

2. 定时策略

  • 避免过于频繁的通知
  • 考虑用户的使用习惯
  • 提供通知频率设置选项

3. 错误处理

  • 始终处理权限请求失败的情况
  • 提供用户友好的错误提示
  • 记录通知发送失败的原因

4. 性能优化

  • 避免同时发送大量通知
  • 及时清理不需要的通知
  • 合理使用重复通知

测试建议

1. 功能测试

  • 测试所有通知类型
  • 验证权限请求流程
  • 检查通知点击处理

2. 兼容性测试

  • 测试不同 iOS 版本
  • 测试不同 Android 版本
  • 验证后台通知功能

3. 用户体验测试

  • 测试通知时机是否合适
  • 验证通知内容是否清晰
  • 检查通知频率是否合理

故障排除

常见问题

  1. 通知不显示

    • 检查权限是否已授予
    • 确认应用是否在前台
    • 验证通知配置是否正确
  2. 定时通知不触发

    • 检查设备是否重启
    • 确认应用是否被系统杀死
    • 验证时间设置是否正确
  3. 权限被拒绝

    • 引导用户到系统设置
    • 提供权限说明
    • 实现降级处理方案

调试技巧

// 启用详细日志
console.log('通知权限状态:', await notificationService.getPermissionStatus());
console.log('已安排通知:', await notificationService.getAllScheduledNotifications());

// 测试通知发送
await notificationService.sendImmediateNotification({
  title: '测试通知',
  body: '这是一个测试通知',
  sound: true
});

总结

本推送通知功能实现完整、功能丰富,支持多种通知类型和场景。通过合理的架构设计和错误处理,确保了功能的稳定性和用户体验。开发者可以根据具体需求灵活使用各种通知功能,为用户提供个性化的提醒服务。