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

React Native Expo安卓应用未弹出通知权限请求弹窗问题

问题

使用Expo + EAS Build开发React Native安卓应用,已按官方文档配置Firebase Cloud Messaging通知功能。代码中通过useEffect在应用启动时检查通知权限,无权限则发起请求,但在开发服务器运行时,弹出提示“Failed to get push token for push notification!”。手动在设备设置中开启通知权限后,应用运行正常,调度通知也能正常工作。想确认:这是否是开发服务器导致的问题?部署后是否会自动弹出权限请求弹窗?

相关代码如下:

import * as Notifications from "expo-notifications";
// other import statements


Notifications.setNotificationHandler({
  handleNotification: async () => {
    return {
      shouldShowAlert: true,
      shouldPlaySound: true,
      shouldSetBadge: true,
    };
  },
});

// other code

export default function App() {

// other code

const notificationListener = useRef();
const responseListener = useRef();

useEffect(() => {
    registerForPushNotificationsAsync().then(token => setExpoPushToken(token));

    // This listener is fired whenever a notification is received while the app is foregrounded
    notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
      setNotification(notification);
    });

    // This listener is fired whenever a user taps on or interacts with a notification (works when app is foregrounded, backgrounded, or killed)
    responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
      // console.log(response);
    });

    return () => {
      Notifications.removeNotificationSubscription(notificationListener.current);
      Notifications.removeNotificationSubscription(responseListener.current);
    };

    // other unrelated code

  }, []);
  
  // code related to the app itself

}

// below is the function i call above upon app launch in order to get notification
// but no prompt comes up for the user

async function registerForPushNotificationsAsync() {

  let token;
  if (Device.isDevice) {
    console.log('about to getPermissionsAsync');
    const { status: existingStatus } = await Notifications.getPermissionsAsync();
    let finalStatus = existingStatus;
    if (existingStatus !== 'granted') {
      console.log('about to requestPermissionsAsync');
      const { status } = await Notifications.requestPermissionsAsync();
      console.log('the status gotten by requestPermissionsAsync() is the line below this: ');
      console.log(status);
      finalStatus = status;
    }
    if (finalStatus !== 'granted') {
      alert('Failed to get push token for push notification!');
      return;
    }
    console.log('about to get token');
    token = (await Notifications.getExpoPushTokenAsync({
      experienceId: '@johnquiet/buglecallexplore ',
    })).data;
    console.log('should see token below this line');
    console.log(token);
  } else {
    alert('Must use physical device for Push Notifications');
  }

  if (Platform.OS === 'android') {
    Notifications.setNotificationChannelAsync('alarms', {
      name: 'Scheduled Notifications',
      importance: Notifications.AndroidImportance.MAX,
      vibrationPattern: [0, 250, 250, 250],
      lightColor: '#a7e7fa',
    });
  }

  return token;
}

// more unrelated code and styles

分析与解决

  1. 先修复代码中的明显错误
    你在getExpoPushTokenAsync里填写的experienceId末尾多了一个空格:'@johnquiet/buglecallexplore ',这个值必须和app.json中expo.slug完全匹配,空格会导致token获取失败,直接触发错误提示。先去掉空格再重新测试。

  2. 开发环境的权限请求逻辑

    • 如果用Expo Go测试,安卓端的权限请求逻辑和EAS Build生成的自定义开发包有差异,Expo Go可能限制部分权限的自动弹窗,建议改用EAS Build的dev build测试,更贴近生产环境。
    • 若用户之前手动拒绝过通知权限,系统会将权限状态设为denied,此时调用requestPermissionsAsync不会再弹出请求弹窗,必须引导用户去设备设置中开启——这个逻辑在开发和生产环境是一致的。
  3. 生产环境的表现
    部署后,首次安装应用的用户权限状态为undetermined,调用requestPermissionsAsync会自动弹出系统权限请求弹窗,和你预期的一致。只有当用户之前拒绝过权限,才需要手动引导开启。

  4. 额外排查建议

    • 查看registerForPushNotificationsAsync中的日志输出,确认requestPermissionsAsync返回的status值:如果是undetermined却没弹窗,可能是SDK版本或设备兼容性问题;如果是denied,则需要添加引导用户去设置开启权限的逻辑。
    • 确保使用最新稳定版的Expo SDK,旧版本可能存在安卓13+通知权限(POST_NOTIFICATIONS)的兼容问题。

内容的提问来源于stack exchange,提问作者John Quiet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:01:07