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

Expo推送通知报错DeviceNotRegistered,请求技术排查

Expo推送通知报错DeviceNotRegistered排查方案

问题概述

基于Expo构建的React Native应用已完成推送通知配置,能正常获取ExponentPushToken,但通过Expo API或官方工具推送时,持续报错:

DeviceNotRegistered: "ExponentPushToken[***]" is not a registered push notification recipient

已实现代码

通知Hook实现

export const useNotifications = () => {
  const registerForPushNotificationsAsync = async () => {
    if (Device.isDevice) {
      const { status: existingStatus } =
        await Notifications.getPermissionsAsync();
      let finalStatus = existingStatus;
      if (existingStatus !== "granted") {
        const { status } = await Notifications.requestPermissionsAsync();
        finalStatus = status;
      }
      if (finalStatus !== "granted") {
        alert("Failed to get push token for push notification!");
        return;
      }
      const token = (await Notifications.getExpoPushTokenAsync()).data;
      console.log("TOKEN------------", token);
      alert(token);
    } else {
      alert("Must use physical device for Push Notifications");
    }

    if (Platform.OS === "android") {
      Notifications.setNotificationChannelAsync("default", {
        name: "default",
        importance: Notifications.AndroidImportance.MAX,
        vibrationPattern: [0, 250, 250, 250],
        lightColor: "#FF231F7C",
      });
    }
  };
   const handleNotification = (notification = Notifications.Notification) => {
    // 自定义通知处理逻辑
  };

  // 通知点击监听器
  const handleNotificationResponse = (
    response = Notifications.NotificationResponse
  ) => {
    const data = ({ url } = response.notification.request.content.data);

    if (data?.url) Linking.openURL(data.url);
  };
  return {
    registerForPushNotificationsAsync,
    handleNotification,
    handleNotificationResponse,
  };
};

组件中使用代码

useEffect(() => {
  registerForPushNotificationsAsync();
  Notifications.setNotificationHandler({
    handleNotification: async () => ({
      shouldShowAlert: true,
      shouldPlaySound: false,
      shouldSetBadge: true,
    }),
  });
  const responseListener =
    Notifications.addNotificationResponseReceivedListener(
      handleNotificationResponse
    );

  return () => {
    if (responseListener) {
      Notifications.removeNotificationSubscription(responseListener);
    }
  };
}, []);

已执行操作

  • 执行eas build -p android --profile preview生成安卓预览包并在真机测试
  • 通过expo push:android:upload --api-key <your-token-here>上传Firebase Cloud Messaging服务器密钥

排查与解决步骤

  • 匹配推送环境与构建配置
    预览包(preview profile)对应Expo的staging环境,推送时必须指定环境:
    使用官方工具推送时添加--staging参数:

    expo push:send --staging --message "测试通知" --to ExponentPushToken[xxx]
    

    调用API时需使用staging端点:https://exp.host/--/api/v2/push/send(默认端点为production,会导致令牌不匹配)

  • 对应Firebase密钥环境
    Firebase Cloud Messaging有两个密钥:生产环境服务器密钥、测试环境服务器密钥。若上传的是生产密钥但用staging环境推送,会导致令牌无法识别。重新上传staging对应的测试密钥:

    expo push:android:upload --api-key <firebase-staging-server-key> --staging
    
  • 验证令牌生成环境
    预览包生成的令牌属于staging环境,不能用生产推送服务发送。部分版本的staging令牌会带有STAGING-前缀,可快速识别。

  • 检查EAS构建配置
    确认eas.json中preview profile的环境配置,避免强制指定production:

    {
      "build": {
        "preview": {
          "android": {
            "buildType": "apk"
          },
          "env": {
            "EXPO_PUBLIC_ENV": "staging"
          }
        }
      }
    }
    
  • 重新生成令牌测试
    卸载现有预览包,重新安装后获取新令牌,立即用对应环境的推送工具测试,避免令牌过期或环境绑定错误。

  • 核对Firebase包名
    确认Firebase项目的包名(applicationId)与EAS构建配置中的android.package完全一致(大小写敏感),包名不匹配会导致Firebase拒绝请求,进而触发Expo的设备未注册错误。


内容的提问来源于stack exchange,提问作者Zaki Kendil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 05:05:18