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

Expo-Notifications前台无法显示本地通知问题求助

Expo Notifications前台不显示通知的解决方案

问题

已配置Expo-Notifications作为本地提醒功能,应用后台运行时通知正常显示,但前台运行时无法弹出通知。相关代码如下:

App.tsx

import * as Notifications from "expo-notifications";

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


const App = () => {

  const notificationListener = useRef();
  const responseListener = useRef();
  const [notification, setNotification] = useState(false);


    useEffect(() => {
      const getPerm = async() => {
        const { status: existingStatus } = await Notifications.getPermissionsAsync();
        let finalStatus = existingStatus
        if(existingStatus !== 'granted'){
          const { lastStatus }:any = await Notifications.requestPermissionsAsync();
          finalStatus = lastStatus
        }
        if (finalStatus !== "granted") {
          console.log("Failed to get push token for push notification!");
          return;
        }
      }
      getPerm()

      notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
        setNotification(notification);
        console.log("NOTIF: ", notification)
      });
  
      responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
        console.log("RES: ",response);
      });
  
      return () => {
        Notifications.removeNotificationSubscription(notificationListener.current);
        Notifications.removeNotificationSubscription(responseListener.current);
      };
    }, []) ....

调度通知代码

const triggerNotifications = async () => {
    await Notifications.scheduleNotificationAsync({
    content: {
        title: "You’ve got mail! 📬",
        body: "Here is the notification body",
        data: { data: "goes here" }
    },
    trigger: { seconds: 5 },
    });
}

解决方案

Expo Notifications 默认在应用前台时不会自动弹出系统通知弹窗,即使设置了shouldShowAlert: true,只会触发监听事件。可以通过以下方式解决:

1. 前台手动触发通知弹窗

在addNotificationReceivedListener中调用Notifications.presentNotificationAsync,强制弹出系统通知:

修改App.tsx中的监听逻辑:

notificationListener.current = Notifications.addNotificationReceivedListener(async (notification) => {
  setNotification(notification);
  console.log("NOTIF: ", notification);
  // 前台运行时手动弹出通知
  await Notifications.presentNotificationAsync(notification.request.content);
});

2. 确认全局通知处理配置生效

确保Notifications.setNotificationHandler在App组件外部、任何通知调度代码之前执行,保证配置全局生效。

3. 完善权限配置

在app.json(或app.config.js)中补充平台权限配置:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "UIBackgroundModes": ["notifications"],
        "NSUserNotificationUsageDescription": "需要发送通知提醒您"
      }
    },
    "android": {
      "permissions": ["POST_NOTIFICATIONS"],
      "useNextNotificationsApi": true
    }
  }
}

完整修改后的关键代码示例

import * as Notifications from "expo-notifications";
import { useState, useEffect, useRef } from "react";

// 全局配置通知处理逻辑,确保优先执行
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
  }),
});

const App = () => {
  const notificationListener = useRef();
  const responseListener = useRef();
  const [notification, setNotification] = useState<Notifications.Notification | null>(null);

  useEffect(() => {
    const getPerm = async () => {
      const { status: existingStatus } = await Notifications.getPermissionsAsync();
      let finalStatus = existingStatus;
      if (existingStatus !== 'granted') {
        const { status: lastStatus } = await Notifications.requestPermissionsAsync();
        finalStatus = lastStatus;
      }
      if (finalStatus !== "granted") {
        console.log("获取通知权限失败!");
        return;
      }
    };
    getPerm();

    notificationListener.current = Notifications.addNotificationReceivedListener(async (notification) => {
      setNotification(notification);
      console.log("NOTIF: ", notification);
      // 前台强制弹出通知
      await Notifications.presentNotificationAsync(notification.request.content);
    });

    responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
      console.log("RES: ", response);
    });

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

  return <></>;
};

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:35:20