React Native集成Firebase时报No Firebase App '[DEFAULT]'错误如何解决
问题原因分析
- 你在构造函数中同步调用了
init()和checkAuth(),firebase.initializeApp()是异步操作,初始化还没完成时,checkAuth()中的firebase.auth()就已经执行,自然找不到已初始化的App实例。 - Firebase初始化逻辑耦合在Chat业务组件中,如果应用有其他组件先加载并调用Firebase能力,也会提前触发该报错。
db、uid等getter属性中直接调用了firebase.database()、firebase.auth(),初始化未完成时这些属性被访问也会抛出错误。
解决方法
调整初始化执行顺序
将checkAuth()的调用移动到init()初始化完成之后,不要和init()同步执行,修改对应代码:
init = async () => { if (!firebase.apps.length) { await firebase.initializeApp({ // 你的Firebase配置项 apiKey: "xxxxxxxxxxxxxxxxxxxxxs", authDomain: "xxxxxxxxxxxxx", databaseURL: "xxxxxxxxxxxxxxxxxxxx", projectId: "xxxxxxxxxxx", storageBucket: "xxxxxxxxxxxx", messagingSenderId: "xxxxxxxxxxxxx", appId: "xxxxxxxxxxxxxxxxxx", measurementId: "xxxxxxxxxxxxx" }) } // 初始化完成后再执行鉴权逻辑 this.checkAuth() }; constructor(props) { super(props); this.state = { messages: [], chatgenidres: '', } // 构造函数只调用init即可 this.init() }
优化初始化位置(更推荐方案)
把Firebase初始化逻辑抽成独立公共文件,在应用入口(如App.js)就完成初始化,从根源避免组件加载时初始化未完成的问题:
- 新建
firebaseConfig.js文件:
import firebase from 'firebase'; const firebaseConfig = { // 你的Firebase配置项 apiKey: "xxxxxxxxxxxxxxxxxxxxxs", authDomain: "xxxxxxxxxxxxx", databaseURL: "xxxxxxxxxxxxxxxxxxxx", projectId: "xxxxxxxxxxx", storageBucket: "xxxxxxxxxxxx", messagingSenderId: "xxxxxxxxxxxxx", appId: "xxxxxxxxxxxxxxxxxx", measurementId: "xxxxxxxxxxxxx" }; if (!firebase.apps.length) { firebase.initializeApp(firebaseConfig); } export default firebase;
- 所有用到Firebase的组件都从该配置文件引入,不要直接引入全局firebase包,Chat组件修改导入语句:
// 替换原有 import firebase from 'firebase' 语句 import firebase from '../../firebaseConfig'; // 同时删除Chat组件中原有的init()方法、以及构造函数中this.init()的调用
增加加载状态兜底
给组件增加初始化加载状态,Firebase初始化完成前不渲染依赖Firebase能力的业务组件,避免运行时报错:
constructor(props) { super(props); this.state = { messages: [], chatgenidres: '', isFirebaseInit: false // 新增初始化状态字段 } this.init() } init = async () => { if (!firebase.apps.length) { await firebase.initializeApp({ // 配置项 }) } this.setState({isFirebaseInit: true}) this.checkAuth() }; render() { // 初始化未完成时可渲染加载占位 if(!this.state.isFirebaseInit) return null // 原有render逻辑保持不变 }
内容的提问来源于stack exchange,提问作者Subham Halder
相关产品推荐
相关产品推荐

