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

Expo项目Firebase报错:TypeError: undefined is not an object (evaluating '_firebase.default.firestore')

Expo + Firebase Firestore 调用报错解决

问题描述

我有一个Expo项目,Firebase配置文件如下:

import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';

const firebaseConfig = {
  ...
};

if (!firebase.apps.length){
  firebase.initializeApp(firebaseConfig);
}

export { firebase };

调用Firestore的代码如下:

const [events, setEvents] = useState([]);
const evsRef = firebase.firestore().collection('testing');

const getEvents = () => {
    evsRef.onSnapshot(
        snapshot => {
            const evs = [];
            snapshot.forEach((doc)=>{
                const {name, height, features:{good, better, best}} = doc.data();
                evs.push({
                    key: doc.id,
                    name, height, 
                    features:
                        {
                            good, 
                            better, 
                            best
                        }
                }) 
            })
            setEvents(evs);
        }
    )
    return;
}

useEffect(() => {
    getEvents();
    console.log('Testing: ', events);
},[events])

运行后抛出错误:

TypeError: undefined is not an object (evaluating '_firebase.default.firestore')

作为React-Native/Expo新手,找不到统一的Firebase/Firestore调用示例,之前用collection(db, 'collection name')能运行,换成当前写法却报错,求解决思路。


解决思路

1. 修正导入导出不匹配问题

你的配置文件用的是具名导出export { firebase },如果调用时用的是默认导入import firebase from './firebase-config',会导致导入的是一个包含firebase属性的对象,而非Firebase实例,自然找不到firestore()方法。

两种修正方案二选一:

  • 方案一:修改配置文件为默认导出
    // 配置文件末尾
    export default firebase;
    
  • 方案二:调用时使用具名导入
    import { firebase } from './你的firebase配置文件路径';
    

2. 确认Firestore兼容模块已正确安装加载

虽然配置文件里导入了'firebase/compat/firestore',但如果依赖未正确安装,也会导致方法缺失。重新执行安装命令:

# npm
npm install firebase@compat
# yarn
yarn add firebase@compat

3. 修复useEffect的逻辑问题(避免内存泄漏)

你的useEffect依赖了events,会导致每次状态更新都重复添加快照监听,引发内存泄漏。调整为仅组件挂载时添加监听,卸载时取消:

useEffect(() => {
    // 保存监听的取消函数
    const unsubscribe = firebase.firestore().collection('testing').onSnapshot(snapshot => {
        const evs = [];
        snapshot.forEach((doc)=>{
            const {name, height, features:{good, better, best}} = doc.data();
            evs.push({
                key: doc.id,
                name, height, 
                features: { good, better, best }
            }) 
        })
        setEvents(evs);
    });
    
    // 组件卸载时取消监听
    return unsubscribe;
}, []) // 空依赖确保只执行一次

另外,原代码里的console.log会因为React状态更新的异步性打印旧值,要查看最新events可以单独加一个监听:

useEffect(() => {
    console.log('Testing: ', events);
}, [events])

4. 关于两种Firestore写法的说明

  • 你之前用的collection(db, 'collection name')是Firebase v9+的模块化写法(支持树摇,体积更小),需要先初始化数据库实例:
    import { getFirestore, collection } from 'firebase/firestore';
    import { firebase } from './firebase-config';
    
    const db = getFirestore(firebase);
    const evsRef = collection(db, 'testing');
    
  • 当前用的firebase.firestore().collection('testing')是v8的兼容写法(compat模式),两种写法都有效,只要保持项目内写法统一即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 01:15:39