Expo Push Notifications仅前台显示,后台无推送问题求助
Expo推送通知仅前台显示,后台无推送问题排查
问题现象
- 自身Expo应用调用Expo Push Notification V2 API发送推送时,通知仅在应用前台显示,后台完全无法接收
- 用Postman或Expo官方推送测试工具发送同一token的通知时,后台可正常接收推送
已完成的排查动作
- 确认后台通知权限、代码配置无误,设备系统设置允许后台通知
- 检查应用内API实现,确认请求参数、响应处理均正确
- 关闭设备省电模式,更换多台物理设备测试
- 构建独立APK测试,问题依旧存在
- 已严格遵循Expo官方推送通知配置指南
应用核心代码
async function registerForPushNotificationsAsync() { let token; 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; } token = (await Notifications.getExpoPushTokenAsync()).data; } 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", }); } return token; } async function sendPushNotification( expoPushToken: any, type?: string, name?: string ) { const message = { to: expoPushToken, sound: "default", title: "HI", body: "BY", }; await fetch("https://exp.host/--/api/v2/push/send", { method: "POST", headers: { Accept: "application/json", "Accept-encoding": "gzip, deflate", "Content-Type": "application/json", }, body: JSON.stringify(message), }); } export default function App() { const { isLoadingComplete, user, error, refresh } = useCachedResources(); const [notifications, setNotifications] = useState<Notification[]>([]); const [expoPushToken, setExpoPushToken] = useState<any>(); const [notification, setNotification] = useState<any>(false); const notificationListener = useRef<any>(); const responseListener = useRef<any>(); useEffect(() => { registerForPushNotificationsAsync().then((token) => setExpoPushToken(token) ); console.log("eee", expoPushToken); notificationListener.current = Notifications.addNotificationReceivedListener((notification) => { setNotification(notification); }); responseListener.current = Notifications.addNotificationResponseReceivedListener( async (response) => { await Notifications.setBadgeCountAsync(0); navRef.navigate("Dashboard", { screen: "Messages", }); } ); return () => { Notifications.removeNotificationSubscription( notificationListener.current ); Notifications.removeNotificationSubscription(responseListener.current); }; }, []); useEffect(() => { const newNotifications = notifications?.filter( (not) => not.status === "new" ); newNotifications?.forEach(async (not) => { await sendPushNotification(expoPushToken, not.type, not.by.name); updateNotification(not.id!!, { status: "old", }); }); }, [notifications]); useEffect(() => { // getFCMToken(); let unsubscribeNotification: Unsubscribe; if (user && user.id) { unsubscribeNotification = subscribeNotification( user.id, handleNotificationChange ); } return () => { if (unsubscribeNotification) { unsubscribeNotification(); } }; }, [user]); const handleNotificationChange = (snapshot: QuerySnapshot<Notification>) => { let result: Notification[] = []; snapshot.forEach((doc) => { result.push({ ...doc.data(), id: doc.id }); }); setNotifications(result); }; }
排查建议
补充请求头的平台标识字段
当前请求头缺少Expo-Platform字段(指定iOS/Android),Postman测试时可能自动带上了该字段,部分场景下后台推送需要它匹配设备类型。尝试在请求头添加:Expo-Platform: android或根据设备动态设置对应值。
明确推送消息的优先级与平台配置
Android后台推送需设置priority为high,iOS需开启contentAvailable(普通通知也建议明确配置)。修改message对象:const message = { to: expoPushToken, sound: "default", title: "HI", body: "BY", priority: "high", contentAvailable: true, android: { priority: "high", channelId: "default" // 与创建的通知渠道ID保持一致 } };校验推送时的token有效性
监听notifications变化的useEffect可能在expoPushToken初始化完成前就调用sendPushNotification,导致发送无效token。添加前置判断:if (!expoPushToken) return; await sendPushNotification(expoPushToken, not.type, not.by.name);查看Expo推送API的响应结果
当前代码未处理API响应,无法知晓Expo服务器是否返回错误。修改sendPushNotification打印响应:const response = await fetch("https://exp.host/--/api/v2/push/send", { // 现有配置 }); const responseData = await response.json(); console.log("推送响应:", responseData);若存在token无效、消息格式错误等问题,可直接定位。
确认Android通知渠道的绑定
确保发送消息时指定了channelId,否则系统可能使用默认渠道,而默认渠道的重要性可能不足以触发后台通知。
内容的提问来源于stack exchange,提问作者Meer Suhana
相关产品推荐
相关产品推荐

