React Native(Expo)推送通知如何从后端动态获取标题与内容
Expo React Native 推送通知无法加载后端数据的解决方案
你当前的核心问题是异步数据加载的时序错误,以及重复通知的内容无法更新:
loadLatestNews是异步请求,调用后立刻执行schedulePushNotification时,newsSource和newsTitle还处于初始空值状态,导致通知内容为空。- 重复触发的通知会一直使用第一次调度时的旧数据,不会自动拉取最新的数据库记录。
具体修复步骤
1. 修复异步请求时序,确保数据加载完成再调度通知
把 loadLatestNews 改成异步函数,用 async/await 等待接口返回数据,同时直接用接口返回值更新状态,避免state异步更新的延迟问题:
const loadLatestNews = async () => { try { const response = await axios.get(url); const data = response.data.data; // 直接更新状态 setNewsTitle(data.title); setNewsSource(data.feedName); setNewsDescription(data.description); setNewsImage(data.image); setNewsPubDate(data.pubDate); setNewsFeedName(data.feedName); setNewsLink(data.link); // 处理作者显示逻辑 const formattedAuthor = (data.author !== 'Editor' && data.author !== 'F1 Desk' && data.author !== 'Motorsport Network' && data.author !== 'RACER Staff' && data.author !== 'GPblog' && data.author !== '') ? `By ${data.author}` : ''; setAuthor(formattedAuthor); // 更新newsItem setNewsItem({ title: data.title, description: data.description, author: formattedAuthor, image: data.image, pubDate: data.pubDate, source: data.feedName, feedName: data.feedName, link: data.link, }); // 数据加载完成后,根据开关状态调度通知 if (isNotificationOn) { await schedulePushNotification(data.feedName, data.title); } } catch (error) { console.log(error); } };
2. 实现通知内容定时更新
Expo的重复通知会固定使用调度时的内容,所以需要定期拉取新数据并替换旧通知:
// 全局保存通知ID,用于取消旧通知 let notificationId = null; async function schedulePushNotification(newsSource, newsTitle) { // 先取消之前的重复通知 if (notificationId) { await Notifications.cancelScheduledNotificationAsync(notificationId); } // 调度新的重复通知 notificationId = await Notifications.scheduleNotificationAsync({ content: { title: newsSource, body: newsTitle, data: { data: 'goes here' }, }, trigger: { seconds: 30, repeats: true }, }); }
3. 调整初始化和定时刷新逻辑
移除原初始化useEffect中直接调用schedulePushNotification的代码,新增依赖通知开关的useEffect处理数据拉取和定时刷新:
// 初始化逻辑 useEffect(() => { retrieveDarkMode(); retrieveNotification(); registerForPushNotificationsAsync().then((token) => { setExpoPushToken(token); }); notificationListener.current = Notifications.addNotificationReceivedListener((notification) => { setNotification(notification); }); responseListener.current = Notifications.addNotificationResponseReceivedListener((response) => { console.log(response); }); return () => { Notifications.removeNotificationSubscription(notificationListener.current); Notifications.removeNotificationSubscription(responseListener.current); }; }, []); // 通知开关状态变化时处理刷新和通知 useEffect(() => { let refreshInterval; if (isNotificationOn) { // 初始化加载一次数据 loadLatestNews(); // 每隔30分钟刷新一次数据(可根据需求调整间隔) refreshInterval = setInterval(() => { loadLatestNews(); }, 30 * 60 * 1000); } else { // 关闭通知时取消已调度的通知 if (notificationId) { Notifications.cancelScheduledNotificationAsync(notificationId); notificationId = null; } } return () => { if (refreshInterval) clearInterval(refreshInterval); }; }, [isNotificationOn]);
内容的提问来源于stack exchange,提问作者f1ian
相关产品推荐
相关产品推荐

