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

React Native POST_NOTIFICATIONS权限自动拒绝且应用异常求助

React Native 通知权限请求失败与 fetchData 重复执行问题

问题描述

在 React Native 项目中,使用 useEffect 执行以下代码时出现两个异常:

  1. 通知权限请求弹窗未弹出,POST_NOTIFICATIONS 权限被自动拒绝;
  2. fetchData() 函数多次执行,导致数组重复显示。

已确认:

  • AndroidManifest.xml 已添加 <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
  • 目标 API 版本为 31 及以上
  • 使用 PushNotification.localNotification 可正常发送本地通知

代码片段:

const requestNotificationPermission = async () => {
  try {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS,
      {
        title: 'Notification Permission',
        message: 'Allow the app to send you notifications',
        buttonNeutral: 'Ask Me Later',
        buttonNegative: 'Cancel',
        buttonPositive: 'OK',
      },
    );
    if (granted === PermissionsAndroid.RESULTS.GRANTED) {
      console.log('Notification permission granted');
    } else {
      console.log('Notification permission denied');
    }
  } catch (err) {
    console.warn(err);
  }
};

useEffect(() => {
  AppState.addEventListener('change', (state) => {
    if (state === 'active') {
      fetchData();
    }
  });
  requestNotificationPermission();
  fetchData();
  getList();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

问题分析与解决方案

一、通知权限请求失败问题

  • API版本兼容问题
    POST_NOTIFICATIONS 是 Android 13(API 33)新增的权限,API 31/32 不存在该权限,此时通知权限默认授予,强行请求不存在的权限会直接返回拒绝。

解决方法:根据系统版本做权限判断:

import { Platform } from 'react-native';

const requestNotificationPermission = async () => {
  try {
    if (Platform.OS === 'android' && Platform.Version >= 33) {
      // API 33+ 请求 POST_NOTIFICATIONS
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS || 'android.permission.POST_NOTIFICATIONS',
        {
          title: 'Notification Permission',
          message: 'Allow the app to send you notifications',
          buttonNeutral: 'Ask Me Later',
          buttonNegative: 'Cancel',
          buttonPositive: 'OK',
        },
      );
      if (granted === PermissionsAndroid.RESULTS.GRANTED) {
        console.log('Notification permission granted');
      } else {
        console.log('Notification permission denied');
      }
    } else {
      console.log('Notification permission is granted by default');
    }
  } catch (err) {
    console.warn(err);
  }
};
  • 权限被永久拒绝
    若用户之前拒绝权限并勾选「不再询问」,系统会直接返回拒绝且不弹窗,需引导用户跳转到设置页开启:
// 在权限拒绝分支添加逻辑
if (granted === PermissionsAndroid.RESULTS.DENIED) {
  console.log('Notification permission denied');
  const canRequest = await PermissionsAndroid.shouldShowRequestPermissionRationale(
    PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
  );
  if (!canRequest) {
    Linking.openSettings();
  }
}
  • 常量缺失问题
    低版本 React Native 可能未内置 POST_NOTIFICATIONS 常量,直接使用字符串 'android.permission.POST_NOTIFICATIONS' 替代即可。

二、fetchData() 重复执行问题

  • StrictMode 触发重复执行
    开发环境下 React 的 StrictMode 会让 useEffect 执行两次,导致 fetchData 被调用两次。生产环境无此问题,开发时可通过防抖或临时移除 StrictMode 解决:
import { debounce } from 'lodash';

const debouncedFetchData = useCallback(debounce(fetchData, 1000), []);

// 在 useEffect 中替换为防抖后的函数
useEffect(() => {
  // ...其他逻辑
  debouncedFetchData();
  // ...
}, [debouncedFetchData]);
  • 未清理 AppState 监听
    当前代码未移除 AppState 监听,组件卸载后监听仍存在,多次挂载会触发重复调用。需在 useEffect 清理函数中移除监听:
useEffect(() => {
  const handleAppStateChange = (state) => {
    if (state === 'active') {
      fetchData();
    }
  };

  AppState.addEventListener('change', handleAppStateChange);
  requestNotificationPermission();
  fetchData();
  getList();

  // 清理监听
  return () => {
    AppState.removeEventListener('change', handleAppStateChange);
  };
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
  • fetchData 内部无重复请求拦截
    给 fetchData 添加加载状态判断,避免同一时间重复请求:
const [isLoading, setIsLoading] = useState(false);

const fetchData = async () => {
  if (isLoading) return;
  setIsLoading(true);
  try {
    // 数据请求逻辑
  } catch (err) {
    // 错误处理
  } finally {
    setIsLoading(false);
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:52:43