【问题标题】:Proper Way To Subscribe for Real-Time Changes on Firestore with React使用 React 在 Firestore 上订阅实时更改的正确方法
【发布时间】:2020-02-21 01:08:19
【问题描述】:

我刚刚开始学习使用 Firestore 和 React 的一些知识。我希望深入了解 Firestore 提供的实时数据库功能。

以下是我在每个对应文件中的代码sn-ps:

UserComponent.js

import React, { Component } from 'react'

class UserPage extends Component {
  constructor (props) {
    super (props)
    this.state = {
      users: []
    }
  }

  componentDidMount () {
    this.props.firebase.getUsers()
    .then(doc => {
      console.log('componentDidMount', 'Data Received')
      this.setState({ users: doc })
    }
  }

  render () {
    const { users } = this.state
    return (
      <div>
        <h1>Users</h1>
        <hr />
        <table>
          <thead></thead>
          <tbody>
            { users.map (user => (
                <tr key={user.uid}>
                  <td>{ user.uid }</td>
                  <td>{ user.name }</td>
                </tr>
              ))
            }
          </tbody>
        </table>
      </div>
    )
  }
}

Firebase.js

import app from 'firebase/app'
import 'firebase/auth'
import 'firebase/database'
import 'firebase/firestore'

const config = {
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_DATABASE_URL,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID 
}

class Firebase {
  constructor (props) {
    app.initializeApp(config)
    this.auth = app.auth()
    this.db = app.database()
    this.firestore = app.firestore()
  }

  getUsers = () => {
    return new Promise((resolve, reject) => {
      this.firestore.collection("users")
      .onSnapshot((snapshot) => {
        console.log('onSnapshot Called!')
        let updatedData = snapshot.docs.map(doc => doc.data())
        resolve(updatedData)
      }, reject)
    })
  }
}

当我直接进入firestore数据库时,修改一个现有的用户记录,console.log我在触发onSnapShot后立即放在getUsers方法中。快照还包含用户记录的更新集。

我可能在这里遗漏了一些东西(或错误地实现了一些东西),因为这些数据永远不会回到用户组件。我寻求一些指导,以确保当我的 firestore 数据库上的用户集合发生更改时,触发侦听器,并且更新的数据将反映在我的应用程序的用户组件上。

我的另一个问题是,在原始 Firebase 实时数据库中,有一个名为 off 的方法,用于取消订阅更改。 Firestore 中的对应物是什么?我假设这需要放在 React 组件的ComponentWillUnmount 中?

谢谢,

【问题讨论】:

    标签: reactjs google-cloud-firestore


    【解决方案1】:

    您的 Firebase.js 应该:

    import app from 'firebase/app'
    import 'firebase/auth'
    import 'firebase/database'
    import 'firebase/firestore'
    
    const config = {
      apiKey: process.env.REACT_APP_API_KEY,
      authDomain: process.env.REACT_APP_AUTH_DOMAIN,
      databaseURL: process.env.REACT_APP_DATABASE_URL,
      projectId: process.env.REACT_APP_PROJECT_ID,
      storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
      messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID 
    }
    
    
    
    const firebase = app.initializeApp(config)
    const auth = app.auth()
    const db = app.database()
    const firestore = app.firestore()
    
    export const getUsers = () => {
        return new Promise((resolve, reject) => {
          firestore.collection("users")
          .onSnapshot((snapshot) => {
            console.log('onSnapshot Called!')
            let updatedData = snapshot.docs.map(doc => doc.data())
            resolve(updatedData)
          }, reject)
        })
      }
    

    您的 UserComponent.js 应该是:

    import React, { Component } from 'react';
    import {getUsers} from './firebase';
    
    class UserPage extends Component {
      constructor (props) {
        super(props);
        this.state = {
          users: [],
        }
      }
    
      componentDidMount(){
        getUsers().then(doc => {
          console.log('componentDidMount', 'Data Received');
          this.setState({ users: doc });
        })
      }
      render(){
        const { users } = this.state
        return (
          <div>
            <h1>Users</h1>
            <hr />
            <table>
              <thead></thead>
              <tbody>
                { users.map (user => (
                    <tr key={user.uid}>
                      <td>{ user.uid }</td>
                      <td>{ user.name }</td>
                    </tr>
                  ))
                }
              </tbody>
            </table>
          </div>
        )
      }
    }
    
    export default App;
    

    您还应该将 UserPage 组件导入您的 App.js 并将其添加到应用程序中呈现,或者您可以直接在主 index.js 文件中呈现 UserPage。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-19
      • 1970-01-01
      • 2020-08-20
      • 2019-12-16
      • 2018-06-25
      • 1970-01-01
      相关资源
      最近更新 更多