更新记录

0.1.3(2026-09-09) 下载此版本

  1. UTS插件, 支持在uniapp/uniappX 中使用

平台兼容性

uni-app(5.0)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× × × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

uni-app x(5.0)

Chrome Safari Android iOS 鸿蒙 微信小程序
× - 12 ×

其他

多语言 暗黑模式 宽屏模式

使用 Uni-app 离线推送插件

环信 uni-app 推送插件集成了第三方离线消息推送服务,为开发者提供低延时、高送达、高并发、不侵犯用户个人数据的离线消息推送服务。当客户端断开连接或应用进程被关闭等原因导致用户离线时,即时通讯 IM 会通过第三方消息推送服务向该离线用户的设备推送消息通知。

插件只负责向厂商通道或 APNs 注册、获取推送 Token,并把用户点击系统通知的数据回传给 JS。离线消息由环信服务端经厂商通道下发到系统通知栏,插件不负责展示消息。

目前支持的手机厂商推送服务包括:华为、荣耀、小米、OPPO、vivo、魅族、APNs 和 FCM。

::: tip 提示 当前交付物为 UTS 插件 easemob-push,通过 uni_modules 集成。旧版原生插件 EMPushUniPluginnativeplugins + uni.requireNativePlugin)已不再作为推荐接入方式。 :::

前提条件

  1. 环信控制台 注册账号,创建应用。
  2. 了解环信即时通讯 IM 的使用限制,详见 使用限制
  3. 已安装 HBuilderX 3.97.0 及以上版本。
  4. 业务工程已接入环信 IM SDK:4.0 使用 easemob-websdk 的 uni-app 入口(usePlugin(..., 'push'));5.0 使用 ChatClient + PushManagersetNativePush)。证书配置、厂商参数和自定义基座两边相同,差别只在 SDK 接入代码。
  5. 必须使用自定义基座或云打包真机运行。标准基座不包含本插件原生代码。
  6. 若使用推送模板,你需要在 环信控制台即时通讯 > 基础功能 > 消息 页面激活。激活后,如需关闭推送模板功能,必须联系商务,因为该操作会删除推送模板相关的所有配置。
  7. 各推送使用的条件:
    • 小米推送:在小米 / Redmi 设备上可用;
    • 华为推送:在华为设备、老荣耀 EMUI 设备上可用;
    • 荣耀推送:在新荣耀 MagicOS 设备上可用;
    • 魅族推送:在魅族设备上可用;
    • OPPO 推送:在 OPPO / 一加 / realme 设备上可用;
    • vivo 推送:在 vivo / iQOO 设备上可用;
    • APNs 推送:在苹果设备上可用;
    • FCM 推送:在安装了 Google Play 服务的设备上可用,且必须离线打包。

插件在 Android 上按设备品牌选择一条通道。若未配置对应厂商参数,或不满足使用条件,会回退到 NORMAL,此时无法收到厂商离线推送。环信 IM SDK 会通过保活手段尽可能保持与服务器的长连接。

::: warning 注意 本插件不支持 HarmonyOS NEXT、H5 和小程序。华为推送仅支持 Android,不支持 HarmonyOS NEXT。 :::

实现流程

步骤 1:上传推送证书至环信控制台

  1. 在第三方推送服务后台注册应用,获取应用信息,开启推送服务。
  2. 环信控制台 配置获取到的应用信息,上传推送证书,实现第三方推送服务与环信即时通讯 IM 的通信。

登录控制台后,进入应用管理,打开 增值服务 > 消息推送(或 证书管理),点击 添加推送证书,按厂商填写证书名称并上传证书或密钥。

::: tip 提示 更多详情,参见 Android 离线推送APNs 离线推送。证书名称必须与后续客户端配置中的名称完全一致:4.0 写在 usePluginconfig 里,5.0 写在 setNativePushcertificates 里。 :::

步骤 2:配置 uni-app 应用支持推送插件

1. 新建 uni-app 工程并引入推送插件

easemob-push 放到业务工程的 uni_modules/ 目录下:

你的 uni-app 工程/
├── uni_modules/
│   └── easemob-push/
├── App.vue
├── manifest.json
└── AndroidManifest.xml          # Android 厂商参数,见下文

2. 配置 uni-app 项目支持推送

打开 manifest.json,选择 App 模块配置,勾选 Push(消息推送),并把 pushRegisterMode 设为 manual,避免 HBuilderX 内置推送与本插件重复注册。

::: warning 注意 不要勾选 uniPush 1.0 或 uniPush 2.0。 :::

3. 配置 Android 厂商参数

证书名称只用于环信侧绑定。厂商 SDK 还需要在宿主工程写入 AppId / AppKey / 证书文件,并保证包名、签名与开放平台一致。

在业务工程根目录创建 AndroidManifest.xml(不是 nativeResources/android/)。云打包会把它合并进最终 APK。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="你的应用包名">
    <application>
        <!-- 小米:纯数字建议加 push_ 前缀,避免被当成 float -->
        <meta-data
            android:name="XIAO_MI_APP_ID"
            android:value="push_你的小米AppId" />
        <meta-data
            android:name="XIAO_MI_APP_KEY"
            android:value="push_你的小米AppKey" />

        <meta-data
            android:name="OPPO_APP_KEY"
            android:value="你的OPPO_AppKey" />
        <meta-data
            android:name="OPPO_APP_SECRET"
            android:value="你的OPPO_AppSecret" />

        <meta-data
            android:name="com.vivo.push.app_id"
            android:value="你的vivo_AppId" />
        <meta-data
            android:name="com.vivo.push.api_key"
            android:value="你的vivo_AppKey" />

        <meta-data
            android:name="MEI_ZU_APP_ID"
            android:value="push_你的魅族AppId" />
        <meta-data
            android:name="MEI_ZU_APP_KEY"
            android:value="你的魅族AppKey" />

        <meta-data
            android:name="com.hihonor.push.app_id"
            android:value="你的荣耀AppId" />
    </application>
</manifest>

package 必须与云打包 / 自定义基座使用的 Android 包名一致。只配置需要的厂商即可。

华为推送额外步骤:

  1. 从 AppGallery Connect 下载当前应用的 agconnect-services.json
  2. 放到 nativeResources/android/assets/agconnect-services.json
  3. 确认文件中的包名、App ID 与基座签名指纹已在华为后台登记。

::: warning 注意

  1. 只配环信证书名称、不写厂商原生参数时,设备会回退到 NORMAL,无法收到离线推送。
  2. 老荣耀 EMUI 设备走华为 HMS,不是荣耀 Push。新荣耀 MagicOS 才使用 com.hihonor.push.app_id
  3. 针对华为推送,该插件仅支持 Android 平台,不支持 HarmonyOS NEXT 系统。

:::

FCM:

云打包默认不带 Firebase / GMS。要启用 FCM 必须离线打包,自行加入 firebase-messagingplay-services-base,并把 google-services.json 放到 Android 宿主工程。未加入依赖时插件会跳过 FCM,不会因此崩溃。

4. 配置 iOS 推送

  1. manifest.json 勾选 Push 模块,pushRegisterMode 设为 manual
  2. 在 Apple Developer 中为 Bundle ID 开启 Push Notifications。
  3. 自定义基座使用 Development profile,并包含当前测试机 UDID。
  4. 正式发布使用 Apple Distribution + App Store profile,不需要绑定用户设备。
  5. 环信控制台上传的 APNs 证书环境必须与当前包一致:开发包用 development,Ad Hoc / App Store 用 production。

推送 entitlement 由 HBuilderX 的 Push 模块和所选 profile 生成,不要在插件内写死 aps-environment

5. 配置通知点击入口

华为、荣耀、OPPO、vivo 的系统通知默认打开应用,点击数据在目标 Activity 的 Intent extras 中。请在环信推送证书中配置统一入口:

厂商 控制台字段
华为 / 荣耀 Action com.hyphenate.push.OnClickNotifyActivity
OPPO / vivo Activity com.hyphenate.push.OnClickNotifyActivity
小米 预定义打开应用或自定义点击 插件两种都处理
魅族 Receiver 或 Activity 插件处理 onNotificationClicked

单条消息也可用环信扩展覆盖默认跳转:

  • huawei_click_action
  • honor_click_action
  • oppo_click_activity
  • vivo_click_activity
  • meizu_click_activity

6. 生成自定义基座

自定义基座是 uni-app 应用运行的底层原生环境。本插件包含原生代码和厂商 SDK,必须打包自定义基座后才能在真机上验证。

修改厂商参数、包名、证书、签名或原生依赖后,必须重新制作自定义基座。

::: tip 提示 打包自定义基座时,需要提供安卓 / 苹果平台签名证书。安卓平台签名证书是开发者后续更新升级已发布 APK 的凭证,需自行生成并妥善保管。具体请参考 Android 平台签名证书(.keystore)生成指南iOS 证书(.p12)和描述文件(.mobileprovision)申请

  • 配置原生插件后,必须打包自定义基座进行测试。
  • FCM 只能够通过离线打包方式构建。
  • FCM 需要在 Android 工程下添加 google-services.json 文件。 :::

步骤 3:集成 easemob-push 插件

UTS 的 JS 代理只导出函数,不导出插件实例。4.0 和 5.0 都从 @/uni_modules/easemob-push 按需 import 这些函数,但交给 IM SDK 的方式不同。

4.0 SDK 5.0 SDK
包入口 easemob-websdk/uniApp/Easemob-chat easemob-websdkChatClient + PushManager
交给 SDK 的方法 只需 { onRegister } 只需 { onRegister, unRegister }
证书字段 MICertificateName certificates.xiaomi
绑定入口 conn.usePlugin({ emPush, config }, 'push') pushManager.setNativePush({ plugin, certificates })
解绑 conn.unbindPushToken() client.logout() 自动解绑,或 pushManager.removePushToken()

通知点击、权限、角标、清通知栏由宿主直接调插件,不经过 IM SDK。这一部分 4.0 / 5.0 相同。

在 4.0 SDK 中使用

安装并引入 4.0 uni-app SDK:

// 安装环信 4.0 SDK
npm install easemob-websdk

// 在工程中引入 SDK
import websdk from 'easemob-websdk/uniApp/Easemob-chat'

4.0 SDK 只会调用 emPush.onRegister。点击、权限、清通知等由宿主自己调插件,不必塞进 emPush

import websdk from 'easemob-websdk/uniApp/Easemob-chat'
import {
  addNotificationListener,
  onRegister,
  requestNotificationAuthorization
} from '@/uni_modules/easemob-push'

const conn = new websdk.connection({
  appKey: 'xxxxx', // 你的环信 App Key
  isFixedDeviceId: true // 推荐使用固定的设备 ID
})

// #ifdef APP-PLUS
conn.usePlugin({
  emPush: { onRegister },
  config: {
    // 必须与环信控制台「证书管理」中上传的名称完全一致
    MICertificateName: 'xxxxxx', // 小米推送证书名称
    OPPOCertificateName: 'xxxxxx', // OPPO 推送证书名称
    HMSCertificateName: 'xxxxxx', // 华为推送证书名称
    VIVOCertificateName: 'xxxxxx', // vivo 推送证书名称,常用格式 appId#appKey
    HONORCertificateName: 'xxxxxx', // 荣耀推送证书名称
    MEIZUCertificateName: 'xxxxxx', // 魅族推送证书名称
    APNsCertificateName: 'xxxxxx', // APNs 推送证书名称
    FCMCertificateName: 'xxxxxx' // FCM 推送证书名称
  }
}, 'push') // 第二个参数为固定值
// #endif

// 退出 IM 登录、多设备互踢时,解绑环信侧 device token
const unbindPushToken = () => {
  conn.unbindPushToken()
}

export default {
  globalData: {
    pushClickPageReady: false,
    pendingPushClicks: []
  },
  onLaunch() {
    // #ifdef APP-PLUS
    requestNotificationAuthorization((ret) => {
      console.log('notification authorization', ret.status)
    })
    addNotificationListener((payload) => {
      // 仅在用户点击系统通知后回调,不表示消息到达
      if (getApp().globalData.pushClickPageReady) {
        uni.$emit('easemob-push-click', payload)
      } else {
        getApp().globalData.pendingPushClicks.push(payload)
      }
    })
    // #endif
  }
}

首页在 onLoad 中消费冷启动点击,避免页面尚未监听时丢失事件:

onLoad() {
  const onClick = (payload) => {
    console.log('push click', payload)
  }
  uni.$on('easemob-push-click', onClick)
  const pending = getApp().globalData.pendingPushClicks.splice(0)
  pending.forEach(onClick)
  getApp().globalData.pushClickPageReady = true
}

::: tip 提示 unRegister() 只注销厂商 SDK,不会解除环信服务端的推送绑定。4.0 退出登录请调用 conn.unbindPushToken()。 :::

4.0 推荐调用时序:

onLaunch:addNotificationListener / requestNotificationAuthorization
    → conn.usePlugin({ emPush: { onRegister }, config }, 'push')
    → conn.open(...)
    → SDK 调用 onRegister,上传 Token 并绑定证书
    → 杀进程后发消息,走厂商 / APNs 离线推送
    → 用户点击通知 → addNotificationListener
    → 退出登录 → conn.unbindPushToken()

不要在退出 IM 后用离线推送验证点击事件,此时用户已解绑。

在 5.0 SDK 中使用

5.0(ChatClient)由可选的 PushManager 管理 Token 注册、证书映射、绑定更新和退出解绑。SDK 只接收 onRegister / unRegister,不包装点击、权限、角标、initPushModule 等 API。

安装并引入 5.0 SDK:

npm install easemob-websdk

import { ChatClient, PushManager } from 'easemob-websdk'

App.vueonLaunch 尽早注册通知点击和权限,不要等 ChatClient 初始化或登录

import {
  addNotificationListener,
  requestNotificationAuthorization
} from '@/uni_modules/easemob-push'

export default {
  globalData: {
    pushClickPageReady: false,
    pendingPushClicks: []
  },
  onLaunch() {
    // #ifdef APP-PLUS
    requestNotificationAuthorization((ret) => {
      console.log('notification authorization', ret.status)
    })
    addNotificationListener((payload) => {
      if (getApp().globalData.pushClickPageReady) {
        uni.$emit('easemob-push-click', payload)
      } else {
        getApp().globalData.pendingPushClicks.push(payload)
      }
    })
    // #endif
  }
}

首页 onLoad 消费冷启动点击的写法与 4.0 相同。

配置 Token 生命周期时,只把 onRegisterunRegister 交给 PushManager

import { ChatClient, PushManager } from 'easemob-websdk'
import { onRegister, unRegister } from '@/uni_modules/easemob-push'

const pushManager = new PushManager()
pushManager.setNativePush({
  plugin: { onRegister, unRegister },
  certificates: {
    // 必须与环信控制台「证书管理」中上传的名称完全一致
    xiaomi: 'xxxxxx',
    oppo: 'xxxxxx',
    huawei: 'xxxxxx',
    vivo: 'xxxxxx',
    honor: 'xxxxxx',
    meizu: 'xxxxxx',
    apns: 'xxxxxx',
    fcm: 'xxxxxx'
  }
})

const client = ChatClient.init({
  appKey: 'xxxxx',
  managers: [pushManager]
})

await client.login({ userId: 'alice', token: 'IM_TOKEN' })

4.0 config 字段与 5.0 certificates 字段对应关系:

4.0 config 5.0 certificates 通道
APNsCertificateName apns APNs
FCMCertificateName fcm FCM
HMSCertificateName huawei 华为
MICertificateName xiaomi 小米
MEIZUCertificateName meizu 魅族
VIVOCertificateName vivo vivo
OPPOCertificateName oppo OPPO
HONORCertificateName honor 荣耀

可以在登录前或登录后调用 setNativePush():登录前配置会在会话就绪后注册;登录后配置会立即启动。Token 获取和上传在后台进行,不改变 login() 的结果

同一启用状态下,相同配置重复设置是幂等操作。若要替换插件或证书,必须先成功调用 removePushToken(),再传入新配置。

观察绑定结果(事件不含 Token、IM Token 或插件原始错误文本,不要打印 onRegister 的完整返回值):

pushManager.addEventHandler('native-push', {
  onPushTokenBound(event) {
    console.log('bound channel', event.channel, event.notifierName)
  },
  onPushTokenBindFailed(event) {
    console.warn('bind failed', event.stage, event.code, event.retryable)
  },
  onPushTokenRemoveFailed(event) {
    console.warn('remove failed', event.code, event.retryable)
  }
})

5.0 解绑语义:

  • await client.logout():SDK 在鉴权上下文清理前限时尝试解绑,随后注销插件;失败不会阻止本地退出。
  • await pushManager.removePushToken():用于应用内「关闭离线通知」。服务端失败时 Promise 拒绝,原配置和绑定状态保持不变。
  • 手动移除成功后,临时断线或自动重连不会恢复推送。再次调用 setNativePush() 才会重新启用。
  • 应用进入后台、进程被杀或可恢复断线不会触发解绑。

::: tip 提示 5.0 不要再调用 conn.usePlugin(..., 'push'),也不要组装完整 emPush 对象。unRegister() 仍只注销厂商 SDK;环信侧解绑走 logout()removePushToken()。 :::

5.0 推荐调用时序:

onLaunch:addNotificationListener / requestNotificationAuthorization
    → pushManager.setNativePush({ plugin, certificates })
    → ChatClient.init({ managers: [pushManager] })
    → client.login(...)
    → SDK 调用 onRegister,上传 Token 并绑定证书
    → 杀进程后发消息,走厂商 / APNs 离线推送
    → 用户点击通知 → addNotificationListener(不经过 SDK)
    → 退出登录 → client.logout()   // 或应用内关闭推送:removePushToken()

步骤 4:测试离线推送

  1. 消息接收方使用自定义基座登录 IM 账号。
  2. 在环信控制台的用户管理中确认该用户已绑定对应推送证书。
  3. 保持登录并杀掉应用(确保进程退出,且客户端与服务器断开)。
  4. 使用另一账号向该用户发送消息。
  5. 设备应弹出系统通知。点击通知后,addNotificationListener 会收到点击数据。
  6. 4.0 退出后调用 unbindPushToken(),5.0 调用 logout()removePushToken(),再到控制台确认证书绑定已解除。

通道说明

push_type 通道 设备
0 APNs iPhone / iPad
1 FCM 需离线打包并加入 Firebase 依赖
2 华为 HMS 华为、老荣耀 EMUI
3 小米 小米 / Redmi
4 魅族 魅族
5 vivo vivo / iQOO
6 OPPO OPPO / 一加 / realme
7 荣耀 新荣耀 MagicOS
8 NORMAL 未检测到可用厂商配置

initPushModule 返回的 pushConfigTypes 是「已配置通道」,不是当前设备选中的通道。当前实际通道以登录后 onRegisterpush_type 为准。

Android 运行时选择优先级:

  1. 已配置 FCM,且 APK 中存在 GMS / Firebase 类。
  2. 当前品牌对应的厂商通道,且 Manifest / assets 参数齐全。
  3. 以上都不满足,则为 NORMAL

iOS 固定走 APNs,push_type0

通知点击数据

addNotificationListener 只在用户点击系统通知后回调,不表示消息到达。

Android payload:

字段 来源别名 说明
to t 接收方
from f 发送方
msgId m 消息 ID
groupId g 群组 ID,单聊可为空
ext e 扩展,可能是对象或 JSON 字符串

无法识别环信字段时,可能带 providerData 原始数据。

iOS payload: APNs userInfo 的 JSON。结构由服务端推送内容决定,不一定包含上述五个字段。

应用被杀死后点击通知,原生层可能先于页面注册回调。插件会缓存一次点击数据;JS 层仍建议按上文示例做页面级队列。

常见问题

1. 即时通讯 IM 在哪些情况不会发送离线推送通知?

若应用在后台运行,则用户仍为在线状态,即时通讯 IM 不会向用户推送消息通知。

应用在后台运行或手机锁屏等情况,若客户端未断开与服务器的连接,则即时通讯 IM 不会发送离线推送通知。

聊天室消息不支持离线推送。发送消息时若设置为只发在线,也不会触发离线推送。

2. 即时通讯 IM 是否支持多设备离线推送?

你可在 环信控制台证书管理 页面配置多设备推送策略。该策略配置对所有推送通道生效:

  • 所有设备离线时,才发送推送消息;
  • 任一设备离线时,都发送推送消息。

多端登录时若有设备被踢下线,即使接入了 IM 离线推送,也收不到离线推送消息。

3. 页面显示已配置小米,但当前是华为 / OPPO 手机?

initPushModule 只反映 Manifest 里已经写入的厂商参数。当前设备实际通道看登录后绑定结果,或调试时 onRegisterpush_type。未写入对应 AppId / AppKey 时会回退到 NORMAL,无法收到离线推送。

4. 改了证书名还是收不到?

证书名只用于环信绑定。同时还要满足:

  • Android 已写入对应厂商 AppId / AppKey,华为还需要 agconnect-services.json
  • 包名、签名与厂商开放平台、环信证书一致;
  • 修改配置后已重新制作自定义基座;
  • 用户保持 IM 登录后杀进程,再由另一账号发消息。

5. 标准基座能跑吗?

不能。必须自定义基座或云打包。

6. unRegister 和环信侧解绑有什么区别?

  • unRegister():注销当前厂商 SDK,不会解除环信服务端绑定。
  • 4.0:退出 IM 登录调用 conn.unbindPushToken()
  • 5.0:client.logout() 会自动尝试解绑;应用内关闭离线通知调用 pushManager.removePushToken()

7. Android setBadge 无效?

Android 为空实现,仅 iOS 生效。

8. Android 13 及以上收不到通知?

Android 13+ 需要用户同意通知权限。可在启动时调用 requestNotificationAuthorization。用户拒绝后,可调用 openSettingsForNotification 引导其前往系统设置。

9. 旧项目还在用 requireNativePlugin('EMPushUniPlugin')

请迁移到 uni_modules/easemob-push,按本文「步骤 3」用函数导入。4.0 只把 { onRegister } 交给 usePlugin;5.0 只把 { onRegister, unRegister } 交给 setNativePush。不要同时集成旧原生插件和本 UTS 插件。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android:INTERNET、ACCESS_NETWORK_STATE、ACCESS_WIFI_STATE、VIBRATE、POST_NOTIFICATIONS(Android 13+ 运行时申请);OPPO/一加 MCS 接收权限;华为/荣耀/vivo 桌面角标权限;小米 MIPUSH_RECEIVE。iOS:远程通知(横幅、声音、角标)。不申请相机、麦克风、通讯录、精确位置、读写相册。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

本插件采集设备推送 Token(厂商 Token 或 APNs deviceToken)、设备品牌/厂商、应用包名,以及用户点击系统通知时的消息标识。Token 回传给宿主应用后,由环信 IM SDK 上传至环信服务器(如 https://a1.easemob.com),用于离线推送绑定。内嵌的小米、华为、荣耀、OPPO、vivo、魅族、APNs、FCM 推送 SDK 会将 Token 及设备标识发送至对应厂商推送服务器,用于注册推送通道和下发系统通知。不采集通讯录、精确位置、相册等与推送无关的数据,不用于广告。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

Copyright (c) EaseMob Inc.

本插件及其源码由环信(EaseMob)提供,用于在 UniApp / uni-app x 中集成环信推送。 未经环信书面许可,不得将本插件用于与环信即时通讯服务无关的商业再分发。

插件目录中的第三方厂商 SDK(小米、OPPO、vivo、华为、荣耀、魅族)归各厂商所有, 使用时须遵守对应开放平台的许可与隐私政策。详见 NOTICE。