我在哪里初始化React应用程序中的Firebase应用程序?

Mar*_*ode 17 javascript firebase reactjs

我正在尝试将Firebase集成到我的React应用程序中,在查看各种教程之后,我似乎无法就放置firebase初始化代码的位置达成共识firebase.initializeApp(config).

我的应用程序的结构是这样的:

- app.js
- components
   |___Index.jsx
   |___Layout.jsx
   |___PageContent.jsx
Run Code Online (Sandbox Code Playgroud)

每个文件如下所示

app.js

是否所有快速设置与服务器端呈现

Index.jsx

import React from 'react';
import Layout from './Layout.jsx';
import PageContent from './PageContent.jsx';
import './global.css';

class Index extends React.Component {
  render() {
    return (
        <Layout title={this.props.title}>
            <PageContent />
        </Layout>
    );
  }
}

export default Index;
Run Code Online (Sandbox Code Playgroud)

PageContent.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import LandingPage from './components/Landing_Page/Landing.jsx';

class PageContent extends React.Component {
    render() {
        return (
            <LandingPage />
        );
    }
}

if (typeof window !== 'undefined') {
    ReactDOM.render(     
        <PageContent />,
        document.getElementById('root')        
    );
}

export default PageContent;
Run Code Online (Sandbox Code Playgroud)

我需要确保Firebase在我网站的每个页面都可用.现在它是一个单页应用程序,但最终我将添加更多.

任何人都可以帮助我理解我可能把数据库初始化代码放在哪里,以便它应用于所有地方吗?

Ali*_*Ali 22

这就是我的方式

Firebase.js旁边创建文件app.js并放入初始化代码

Firebase.js文件

import * as firebase from 'firebase';

let config = {
    apiKey: "XXXXXXX",
    authDomain: "XXXXX",
    databaseURL: "XXXXX",
    projectId: "XXXXX",
    storageBucket: "XXXX",
    messagingSenderId: "XXXX"
};
firebase.initializeApp(config);

export default firebase;
Run Code Online (Sandbox Code Playgroud)

然后Firebase.js,例如,在每个要使用它的位置导入文件

import React from 'react';    
import firebase from './../Firebase.js'     // <------  import firebase

class Test extends React.Component {

    componentDidMount(){
        firebase.database().ref().child("X").on('value' , {...});
    }

    render() {
        return (
            <h1>Hello</h1>
        );
    }
}

export default Test;
Run Code Online (Sandbox Code Playgroud)

  • @NitishDhar 的建议是不必要的。ES6 模块是单例,在运行时开始为每个文件创建一个实例。因此 `initialiseApp` 只会被调用一次。快乐的时光!我创建了一个简单的沙箱,显示以下内容:https://codesandbox.io/s/sharp-feather-9pf04?file=/src/index.js (15认同)
  • 这会不会多次初始化firebase吗? (7认同)
  • 您可以像单例一样进行初始化`export default !firebase.apps.length ? firebase.initializeApp(config) : firebase.app();` 避免多次初始化 (7认同)
  • 这似乎是一个不错的选择,但仅考虑@NitishDhar 的最后评论以避免多个 Firebase 应用程序初始化。 (2认同)
  • 有人介意解释一下上面的评论吗?ES6 模块不是只评估一次吗?因此,如果没有建议的单例解决方案,Firebase 应用程序只会初始化一次? (2认同)

小智 10

创建名为 firebase.js 的文件

import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";

const firebaseConfig = {
  apiKey: 'AIzaXXXXXXXXXXXXXXXXXXXXXXX',
  authDomain: 'test-XXXX.firebaseapp.com',
  databaseURL: 'https://test-db.firebaseio.com',
  projectId: 'test-XXXX',
  storageBucket: 'test-bucket.appspot.com',
  messagingSenderId: 'XXXXXXX',
  appId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
};


firebase.initializeApp(firebaseConfig);
export const firebaseAuth = firebase.auth();
export const firestore = firebase.firestore()

Run Code Online (Sandbox Code Playgroud)

然后按如下方式使用它:

import { firebaseAuth } from 'firebase'
import SigninForm from 'signin.js'

const ModalSignIn = props => {

  const [email, setEmail] = useState()
  const [password, setPassword] = useState()

  const handleSubmit = e => {
    e.preventDefault()
    firebaseAuth
      .signInWithEmailAndPassword(email, password)
      .then(res => {
        console.log(res.user)
      })
      .catch(err => {
        const { code, message } = err
        console.log(code, message)
      })
  }

  return (<SigninForm/>)
Run Code Online (Sandbox Code Playgroud)


Xle*_*lee 2

看来您想要的是 firebase 可以在全局范围内供您的反应组件使用。

在使用redux之前也是同样的问题,react组件是如何消费全局状态树的?全局变量?来吧,我们就会知道全局变量是邪恶的。反应道具?它看起来非常反应,但是将 props 从 root 传递到 leaf 组件并不有趣。

Context API来救援。您只需要 firebase 绑定即可进行反应,就像 redux/react-router 那样。

假设你不想重新发明轮子,

当然,您也可以通过刚才提到的 React 上下文构建自己的 React Firebase 绑定。

  • 使用 Context API 非常有用,但是,我发现这给我带来了一个问题:我需要访问 actions.js 文件中的 Firebase.auth 实例,我在其中使用 Redux-thunk 登录用户并分派操作使用 UserID 更新我的 Redux 存储。由于 Context Provider 将数据传递给包装的组件,因此无法实现这一点,因为 actions.js 文件不是组件。我找不到任何直接访问提供者的方法。 (2认同)