React Native Expo集成FCM报错:未初始化Firebase App[DEFAULT]
解决Expo React Native推送Token生成时Firebase未初始化的错误
核心问题分析
你遇到的Firebase: No Firebase App [DEFAULT] has been created错误,主要源于两个问题:
- 代码结构违规(
useEffect被嵌套在普通函数内) - 混淆了Expo推送机制与
react-native-firebase的初始化逻辑(Expo的expo-notifications无需手动初始化Firebase,除非额外集成了react-native-firebase)
解决方案步骤
1. 修正代码结构错误
React Hooks规则要求useEffect只能在组件顶层调用,你的代码将其嵌套在了registerForPushNotificationsAsync函数内,这会导致执行异常。以下是修正后的完整代码:
import React, { useState, useEffect, useRef } from 'react'; import { View, Text, Alert } from 'react-native'; import * as Device from 'expo-device'; import * as Notifications from 'expo-notifications'; import Constants from "expo-constants"; Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowAlert: true, shouldPlaySound: false, shouldSetBadge: false, }), }); export default function App() { // 声明必要的状态变量与引用 const [expoPushToken, setExpoPushToken] = useState(''); const [notification, setNotification] = useState(null); const notificationListener = useRef(); const responseListener = useRef(); 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.alert('Failed to get push token for push notification!'); return; } // 获取Expo推送Token,projectId可自动获取,也可手动指定 token = await Notifications.getExpoPushTokenAsync({ projectId: Constants.expoConfig?.extra?.eas?.projectId || process.env.EXPO_PROJECT_ID, }); console.log('Expo Push Token:', token); return token; } else { Alert.alert('Must use physical device for Push Notifications'); return null; } } // 顶层调用useEffect useEffect(() => { registerForPushNotificationsAsync().then(token => { if (token) setExpoPushToken(token.data); }); // 监听通知接收与响应 notificationListener.current = Notifications.addNotificationReceivedListener(notification => { setNotification(notification); }); responseListener.current = Notifications.addNotificationResponseReceivedListener(response => { console.log('Notification Response:', response); }); // 清理监听 return () => { if (notificationListener.current) { Notifications.removeNotificationSubscription(notificationListener.current); } if (responseListener.current) { Notifications.removeNotificationSubscription(responseListener.current); } }; }, []); return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 }}> <Text style={{ marginBottom: 10 }}>Expo Push Token:</Text> <Text style={{ fontSize: 12, textAlign: 'center' }}>{expoPushToken}</Text> {notification && ( <View style={{ marginTop: 20 }}> <Text>Received Notification:</Text> <Text style={{ fontSize: 12 }}>{JSON.stringify(notification.request.content)}</Text> </View> )} </View> ); }
2. 处理Firebase初始化冲突
- 若未使用
react-native-firebase其他功能:直接卸载所有@react-native-firebase/*相关依赖,expo-notifications已封装FCM推送逻辑,无需手动初始化Firebase。 - 若必须集成
react-native-firebase:在App启动时手动初始化Firebase,将以下代码添加到App.js最顶部:
import firebase from '@react-native-firebase/app'; if (!firebase.apps.length) { firebase.initializeApp(); }
3. 验证项目配置一致性
- 确认
app.json中android.package与google-services.json里的package_name完全一致(包括大小写)。 - 检查
Constants.expoConfig.extra.eas.projectId是否正确,可在Expo Dashboard项目设置中获取项目ID,或直接使用process.env.EXPO_PROJECT_ID(Expo自动注入)。 - 确保Expo Dashboard的项目推送设置中,已添加正确的Firebase Cloud Messaging服务器密钥(从Firebase控制台项目设置>云消息获取)。
4. 重新构建开发客户端
修改google-services.json或app.json后,热重载不会生效,必须重新构建开发客户端:
eas build --profile development --platform android
将构建后的APK安装到真机,再用npx expo start --dev-client启动测试。
内容的提问来源于stack exchange,提问作者Omar
相关产品推荐
相关产品推荐

