npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bbhxwl/jpush-expo-plugin

v1.0.0

Published

Expo config plugin for JPush (极光推送) - Compatible with Expo SDK 54+

Downloads

26

Readme

jpush-expo-plugin

极光推送 (JPush) Expo 配置插件,兼容 Expo SDK 49+。

安装

# 使用 npm
npm install jpush-expo-plugin jpush-react-native jcore-react-native

# 使用 yarn
yarn add jpush-expo-plugin jpush-react-native jcore-react-native

# 使用 pnpm
pnpm add jpush-expo-plugin jpush-react-native jcore-react-native

配置

1. 添加插件配置

app.jsonapp.config.js 中添加插件:

app.json

{
  "expo": {
    "plugins": [
      [
        "jpush-expo-plugin",
        {
          "appKey": "你的极光AppKey",
          "channel": "developer-default"
        }
      ]
    ]
  }
}

app.config.js / app.config.ts

export default {
  expo: {
    plugins: [
      [
        'jpush-expo-plugin',
        {
          appKey: '你的极光AppKey',
          channel: 'developer-default',
          production: false,
          enableEntitlements: true,
        },
      ],
    ],
  },
};

2. 生成原生项目

npx expo prebuild

3. 运行项目

# Android
npx expo run:android

# iOS
npx expo run:ios

插件参数

| 参数 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | appKey | string | 是 | - | 极光控制台获取的 AppKey | | channel | string | 是 | - | 渠道名称,用于统计分发渠道 | | production | boolean | 否 | false | iOS 是否使用生产环境(App Store 发布时设为 true) | | enableEntitlements | boolean | 否 | true | iOS 是否自动配置推送权限 |

代码中使用

基础初始化

import { useEffect } from 'react';
import JPush from 'jpush-react-native';

export default function App() {
  useEffect(() => {
    // 初始化极光推送
    JPush.init({
      appKey: '你的极光AppKey',
      channel: 'developer-default',
      production: false,
    });

    // 获取 RegistrationID
    JPush.getRegistrationID((result) => {
      console.log('RegistrationID:', result.registerID);
    });
  }, []);

  return (
    // your app
  );
}

完整示例

import { useEffect } from 'react';
import { Platform } from 'react-native';
import JPush from 'jpush-react-native';

export default function App() {
  useEffect(() => {
    initJPush();
    return () => {
      // 清理监听器
      JPush.removeListener();
    };
  }, []);

  const initJPush = () => {
    // 初始化
    JPush.init({
      appKey: '你的极光AppKey',
      channel: 'developer-default',
      production: false,
    });

    // 获取 RegistrationID
    JPush.getRegistrationID((result) => {
      console.log('RegistrationID:', result.registerID);
    });

    // 监听收到推送通知
    JPush.addNotificationListener((notification) => {
      console.log('收到通知:', notification);
      // notification 结构:
      // {
      //   messageID: string,
      //   title: string,
      //   content: string,
      //   extras: object,
      //   badge: number (iOS),
      //   ring: string (Android),
      //   notificationEventType: 'notificationArrived' | 'notificationOpened'
      // }
    });

    // 监听自定义消息
    JPush.addCustomMessageListener((message) => {
      console.log('收到自定义消息:', message);
    });

    // 监听本地通知
    JPush.addLocalNotificationListener((notification) => {
      console.log('收到本地通知:', notification);
    });

    // iOS: 请求通知权限
    if (Platform.OS === 'ios') {
      JPush.requestNotificationAuthorization((result) => {
        console.log('通知权限:', result);
      });
    }
  };

  // 设置别名(用于指定用户推送)
  const setAlias = (alias: string) => {
    JPush.setAlias({
      alias: alias,
      sequence: Date.now(),
    });
  };

  // 删除别名
  const deleteAlias = () => {
    JPush.deleteAlias({
      sequence: Date.now(),
    });
  };

  // 设置标签(用于分组推送)
  const setTags = (tags: string[]) => {
    JPush.setTags({
      tags: tags,
      sequence: Date.now(),
    });
  };

  // 添加标签
  const addTags = (tags: string[]) => {
    JPush.addTags({
      tags: tags,
      sequence: Date.now(),
    });
  };

  // 删除标签
  const deleteTags = (tags: string[]) => {
    JPush.deleteTags({
      tags: tags,
      sequence: Date.now(),
    });
  };

  // 清空所有标签
  const cleanTags = () => {
    JPush.cleanTags({
      sequence: Date.now(),
    });
  };

  // 设置角标数字 (iOS)
  const setBadge = (badge: number) => {
    JPush.setBadge({
      badge: badge,
      appBadge: badge,
    });
  };

  return (
    // your app
  );
}

使用 Hook 封装

// hooks/useJPush.ts
import { useEffect, useCallback } from 'react';
import { Platform } from 'react-native';
import JPush from 'jpush-react-native';

interface JPushConfig {
  appKey: string;
  channel: string;
  production?: boolean;
}

interface NotificationCallback {
  onNotificationArrived?: (notification: any) => void;
  onNotificationOpened?: (notification: any) => void;
  onCustomMessage?: (message: any) => void;
}

export function useJPush(config: JPushConfig, callbacks?: NotificationCallback) {
  useEffect(() => {
    // 初始化
    JPush.init({
      appKey: config.appKey,
      channel: config.channel,
      production: config.production ?? false,
    });

    // 监听通知
    JPush.addNotificationListener((notification) => {
      if (notification.notificationEventType === 'notificationArrived') {
        callbacks?.onNotificationArrived?.(notification);
      } else if (notification.notificationEventType === 'notificationOpened') {
        callbacks?.onNotificationOpened?.(notification);
      }
    });

    // 监听自定义消息
    JPush.addCustomMessageListener((message) => {
      callbacks?.onCustomMessage?.(message);
    });

    // iOS 请求权限
    if (Platform.OS === 'ios') {
      JPush.requestNotificationAuthorization(() => {});
    }

    return () => {
      JPush.removeListener();
    };
  }, []);

  const setAlias = useCallback((alias: string) => {
    JPush.setAlias({ alias, sequence: Date.now() });
  }, []);

  const deleteAlias = useCallback(() => {
    JPush.deleteAlias({ sequence: Date.now() });
  }, []);

  const setTags = useCallback((tags: string[]) => {
    JPush.setTags({ tags, sequence: Date.now() });
  }, []);

  const getRegistrationID = useCallback(() => {
    return new Promise<string>((resolve) => {
      JPush.getRegistrationID((result) => {
        resolve(result.registerID);
      });
    });
  }, []);

  return {
    setAlias,
    deleteAlias,
    setTags,
    getRegistrationID,
  };
}

使用 Hook:

import { useJPush } from './hooks/useJPush';

export default function App() {
  const { setAlias, setTags, getRegistrationID } = useJPush(
    {
      appKey: '你的极光AppKey',
      channel: 'developer-default',
      production: false,
    },
    {
      onNotificationArrived: (notification) => {
        console.log('通知到达:', notification);
      },
      onNotificationOpened: (notification) => {
        console.log('通知被点击:', notification);
        // 处理通知点击,如跳转页面
      },
      onCustomMessage: (message) => {
        console.log('自定义消息:', message);
      },
    }
  );

  // 登录后设置别名
  const handleLogin = async (userId: string) => {
    setAlias(userId);
  };

  return (
    // your app
  );
}

插件配置说明

Android 配置

插件会自动完成以下配置:

  • 添加权限:POST_NOTIFICATIONSVIBRATERECEIVE_BOOT_COMPLETED
  • AndroidManifest.xml 中添加 JPUSH_APPKEYJPUSH_CHANNEL
  • build.gradle 中配置 manifestPlaceholders

iOS 配置

插件会自动完成以下配置:

  • Info.plist 中添加 remote-notification 后台模式
  • Entitlements 中配置 aps-environment(开发/生产)

iOS 额外步骤

  1. Apple Developer 控制台启用 Push Notifications 功能
  2. 创建并下载 APNs 证书或密钥
  3. 极光控制台 上传证书或配置密钥
  4. 发布到 App Store 时,将 production 设置为 true

常见问题

Q: iOS 收不到推送?

  1. 确认已在 Apple Developer 启用推送功能
  2. 确认已上传 APNs 证书到极光控制台
  3. 检查 production 参数是否正确(开发用 false,生产用 true
  4. 真机测试,模拟器不支持推送

Q: Android 收不到推送?

  1. 确认 appKeychannel 配置正确
  2. 检查是否有厂商通道配置(华为、小米、OPPO 等)
  3. 确认应用未被系统杀死

Q: 如何获取 RegistrationID?

JPush.getRegistrationID((result) => {
  console.log('RegistrationID:', result.registerID);
});

Q: 如何在 EAS Build 中使用?

正常配置即可,EAS Build 会自动执行 prebuild 并应用插件配置。

eas build --platform all

相关链接

License

MIT