You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Capacitor构建的Ionic Angular应用内发送推送通知

核心实现逻辑

首先明确一个强制规则:Firebase Cloud Messaging 不允许直接从客户端应用向其他设备发送推送,所有推送发送请求必须经过你可控的后端服务调用FCM/APNs接口触发——如果把FCM服务端密钥放在前端代码里,会被反编译泄露,任何人都能盗用你的配额给你的用户发垃圾推送,严重时会直接被Google封禁Firebase项目权限。

你现在已经完成了终端设备的推送注册、token获取、接收监听的基础逻辑,要实现业务场景的自动推送,整体只需要补3个环节:

  • 第一步:把用户拿到的设备推送token和当前登录的用户ID绑定,存到你的业务数据库
  • 第二步:在业务触发点(比如入群申请提交、新消息发送成功)调用你自己的后端接口,把推送接收人、推送标题、内容、跳转参数传给后端
  • 第三步:后端拿到请求后,调用FCM官方服务端接口给对应目标token发推送,终端用户就能自动收到系统通知

前端代码改造点

你现有的NotificationsService只完成了推送权限申请和基础接收监听,缺两个核心逻辑:拿到token后上报后端绑定用户、应用前台状态下的通知弹窗兼容,改造后的可直接参考的代码如下:

import { Injectable } from '@angular/core';
import { Capacitor } from '@capacitor/core';
import {
  ActionPerformed,
  PushNotificationSchema,
  PushNotifications,
  Token,
} from '@capacitor/push-notifications';
import { HttpClient } from '@angular/common/http';
import { AuthService } from './auth.service'; // 替换为你项目自己的登录态服务,用于获取当前登录用户ID
import { LocalNotifications } from '@capacitor/local-notifications'; // 用于前台收到推送时手动弹系统通知条

@Injectable({
  providedIn: 'root'
})
export class NotificationsService {
  // 替换为你自己的后端服务接口地址
  private readonly apiBase = 'https://your-backend-domain/api';

  constructor(
    private http: HttpClient,
    private auth: AuthService
  ) { }

  initPush() {
    if (Capacitor.getPlatform() !== 'web') {
      this.registerPush();
    }
  }

  public registerPush() {
    PushNotifications.requestPermissions().then((permission) => {
      if (permission.receive === 'granted') {
        // 向APNs/FCM注册推送服务
        PushNotifications.register();
      }
    });

    PushNotifications.addListener(
      'registration',
      (token: Token) => {
        console.log('当前设备推送token:', token.value);
        // 核心逻辑:将token和当前用户绑定上报到后端存储
        this.uploadPushToken(token.value).subscribe();
      }
    );

    PushNotifications.addListener('registrationError', (error: any) => {
      console.log('推送注册失败:', error);
    });

    // 应用在前台打开时,系统默认不会弹通知条,需要手动触发本地通知
    PushNotifications.addListener(
      'pushNotificationReceived',
      async (notification: PushNotificationSchema) => {
        console.log('收到推送内容:', notification);
        await LocalNotifications.schedule({
          notifications: [
            {
              title: notification.title || '',
              body: notification.body || '',
              id: Date.now(),
              extra: notification.data
            }
          ]
        });
      }
    );

    PushNotifications.addListener(
      'pushNotificationActionPerformed',
      async (notification: ActionPerformed) => {
        const data = notification.notification.data;
        console.log('用户点击推送:', notification.notification);
        if (data.detailsId) {
          // 在这里写跳转逻辑,比如跳转到对应群聊页、入群审核页
          // this.router.navigateByUrl(`/group/${data.groupId}`);
        }
      }
    );
  }

  // 上报推送token到后端的方法
  private uploadPushToken(token: string) {
    const currentUserId = this.auth.getCurrentUserId();
    return this.http.post(`${this.apiBase}/push-token/bind`, {
      userId: currentUserId,
      deviceToken: token,
      platform: Capacitor.getPlatform()
    });
  }
}

后端实现要点

后端不需要复杂逻辑,只需要实现两个基础能力即可:

  1. token绑定接口:接收前端上报的用户ID和设备token,存入数据库。注意一个用户可能在多个设备登录(手机、平板),要存多条token记录,用户主动退出登录时要同步删除对应设备的token,避免给已登出的设备发推送。
  2. 通用推送触发逻辑:在业务事件完成后自动触发推送,流程为:
    • 根据业务场景定位需要接收通知的用户ID,从数据库查询该用户绑定的所有有效设备token
    • 用Firebase Admin SDK初始化FCM服务(服务账号密钥仅存在后端,绝对不能下发到前端)
    • 构造推送消息体,填入标题、正文、自定义跳转参数,批量向目标token下发推送

业务场景示例:用户A提交加入群组B的申请时,前端调用后端的入群申请接口,后端完成入群申请数据写入后,立刻查询群组B群主绑定的所有设备token,调用FCM接口发送标题为「入群申请」、内容为${用户A的昵称} 想要加入你的群组的推送,群主的设备不管应用在前台、后台还是被杀进程,都能收到系统通知。新消息提醒的触发逻辑完全一致,在消息入库完成后触发推送即可。


注意事项
  • iOS平台需要额外配置APNs推送证书,上传到Firebase控制台后才能正常收到推送
  • 推送内容属于明文传输,不要在推送的自定义参数里放密码、身份证号这类敏感信息
  • 不要尝试在前端直接调用FCM的发送接口,服务端凭证泄露会导致项目被滥用
  • 用户关闭推送权限时,要在前端做合理的弹窗引导,避免用户错过关键通知

内容的提问来源于stack exchange,提问作者Idrees Ageed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 05:36:25