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

React Native Expo推送通知自动触发异常问题求助

问题:React Native Expo 自动触发推送通知无效,手动触发正常

我开发的React Native Expo应用核心功能是从Google Sheet拉取数据展示,目前通过每20秒调用fetchData检查新数据。当检测到新数据时调用sendNotification发送通知,但只有手动点击按钮触发时通知正常,自动触发时完全没反应。


相关代码

数据获取与通知触发逻辑

const fetchData = async () => {
    setIsFetching(true); 
    try {
      const data = await FetchData();
      setValue(data);

      const newLength = data.length; 
      let hasNewItems = false; 

      if (data && newLength > prevLengthRef.current) {
        console.log("New Order Received:",newLength - prevLengthRef.current,"new items added");
        await sendNotification(expoPushToken);
        hasNewItems = true; // Set flag if new items found
        setInitialLength(newLength);
        prevLengthRef.current = newLength;
      } else {
        console.log("No new orders received.");
      }
    } catch (error) {
      console.error("Error:", error.message);
    } 
};

定时执行逻辑

useEffect(() => {
  fetchData(); // Initial fetch

  const intervalId = setInterval(fetchData, 20000); // Fetch data every 20 seconds

  return () => clearInterval(intervalId);
}, []); 

通知发送函数

const sendNotification = async () => {
    try {
      console.log("Sending push notification...");
      // notification message
      const message = {
        to: expoPushToken,
        sound: "default",
        title: "New Order ",
        body: "Open the app new order received 🚀",
      };

      await fetch("https://exp.host/--/api/v2/push/send", {
        method: "POST",
        headers: {
          host: "exp.host",
          accept: "application/json",
          "accept-encoding": "gzip, deflate",
          "content-type": "application/json",
        },
        body: JSON.stringify(message),
      });
      console.log("Notification sent successfully!");
    } catch (error) {
      console.error("Error sending notification:", error);
      Alert.alert("Error", "Failed to send notification");
    }
};

手动触发按钮

<Button title="Send push notification" onPress={sendNotification} />

可能的原因及解决方法

1. Expo Push Token 未正确初始化

自动触发时expoPushToken可能还没获取完成,或者已失效。

  • 调整定时逻辑,确保在token拿到后再启动:
useEffect(() => {
  if (!expoPushToken) return;
  
  fetchData();
  const intervalId = setInterval(fetchData, 20000);
  return () => clearInterval(intervalId);
}, [expoPushToken]);

2. 系统限制后台定时器执行

iOS和Android在应用后台/设备休眠时会限制setInterval的执行频率,导致定时任务失效。

  • 改用Expo官方的BackgroundFetch实现后台刷新:
import * as TaskManager from 'expo-task-manager';
import * as BackgroundFetch from 'expo-background-fetch';

const BACKGROUND_FETCH_TASK = 'background-fetch-task';

TaskManager.defineTask(BACKGROUND_FETCH_TASK, async () => {
  try {
    await fetchData();
    return BackgroundFetch.Result.NewData;
  } catch (error) {
    return BackgroundFetch.Result.Failed;
  }
});

useEffect(() => {
  async function registerBackgroundFetch() {
    return BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, {
      minimumInterval: 60, // 系统允许的最小间隔为60秒
      stopOnTerminate: false,
      startOnBoot: true,
    });
  }
  registerBackgroundFetch();
}, []);

3. 通知权限未配置完整

  • 启动时主动请求通知权限,并允许前台显示通知:
import * as Notifications from 'expo-notifications';

useEffect(() => {
  async function requestPermissions() {
    const { status } = await Notifications.requestPermissionsAsync();
    if (status !== 'granted') {
      Alert.alert('权限不足', '需要开启通知权限才能接收推送');
    }
    // 配置前台通知显示规则
    Notifications.setNotificationHandler({
      handleNotification: async () => ({
        shouldShowAlert: true,
        shouldPlaySound: true,
        shouldSetBadge: false,
      }),
    });
  }
  requestPermissions();
}, []);

4. 推送API调用未捕获真实错误

自动触发时可能存在网络请求失败但未打印详细信息的情况:

  • 在sendNotification中添加响应日志:
const response = await fetch("https://exp.host/--/api/v2/push/send", { ... });
console.log('推送API响应:', await response.json());

根据返回的错误信息调整请求参数或检查token有效性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 07:45:19