在Expo Snack中基于类组件实现React Native定时通知方案咨询
解决方案
一、解决Firebase Cloud Messaging的token获取报错问题
你遇到的_firebase.default.messaging.requestPermission is not a function错误,核心原因是Expo环境不能直接使用原生firebase包的messaging方法,必须用Expo官方封装的expo-firebase-messaging,且方法名是requestPermissionsAsync()而非requestPermission。
类组件中的实现步骤:
- 在Expo Snack的package.json中添加
expo-firebase-messaging依赖(Snack会自动完成安装) - 在App.js中初始化并获取token:
import React from 'react'; import { View, Text } from 'react-native'; import * as FirebaseMessaging from 'expo-firebase-messaging'; class App extends React.Component { componentDidMount() { this.setupFCM(); } async setupFCM() { // 请求通知权限 const { status } = await FirebaseMessaging.requestPermissionsAsync(); if (status === 'granted') { // 获取推送token const token = await FirebaseMessaging.getExpoPushTokenAsync(); console.log('FCM Token:', token); // 可在此将token发送至后端存储 } else { console.log('通知权限被拒绝'); } } render() { // 你的栈导航渲染逻辑 return <View><Text>App内容</Text></View>; } } export default App;
注意:使用FCM需在Firebase控制台完成项目配置,并在Snack的项目设置中填入对应Firebase配置信息。
二、实现按日期的日程推送通知(更适配你的场景)
如果仅需针对本地条目/事件按日期推送,推荐使用expo-notifications实现本地日程通知,无需依赖FCM,可直接在Expo Go中运行:
- 在Snack的package.json中添加
expo-notifications依赖 - 在类组件中封装通知调度逻辑:
import React from 'react'; import { View, Button } from 'react-native'; import * as Notifications from 'expo-notifications'; // 配置通知展示规则 Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowAlert: true, shouldPlaySound: true, shouldSetBadge: false, }), }); class HomeScreen extends React.Component { async scheduleNotification(date, title, body) { // 请求通知权限 const { status } = await Notifications.requestPermissionsAsync(); if (status !== 'granted') { alert('需开启通知权限才能使用此功能'); return; } // 调度指定日期的通知 const notificationId = await Notifications.scheduleNotificationAsync({ content: { title: title, body: body, sound: true, }, trigger: { date: new Date(date), }, }); console.log('已创建通知ID:', notificationId); } render() { // 示例:点击按钮调度明日的通知 return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Button title="调度明日事件提醒" onPress={() => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); this.scheduleNotification(tomorrow, '明日日程提醒', '别忘了你的待办事件!'); }} /> </View> ); } } export default HomeScreen;
- 集成到现有栈导航:
在你的navigate.js中,将HomeScreen加入栈即可,类组件的栈导航配置与函数式组件一致:
import { createStackNavigator } from '@react-navigation/stack'; import HomeScreen from './home'; import App from './app'; const Stack = createStackNavigator(); function Navigator() { return ( <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="App" component={App} /> </Stack.Navigator> ); } export default Navigator;
关键注意事项
- Expo Snack中所有依赖必须通过package.json添加,不能使用本地npm安装方式
- 本地日程通知在Expo Go中,即使APP处于后台或关闭状态,到指定时间仍会触发(需确保系统通知权限已开启)
- 若需跨设备推送,再使用FCM;单设备日程提醒场景下,本地通知更轻量化、易实现
内容的提问来源于stack exchange,提问作者Bebu Babu
相关产品推荐
相关产品推荐

