【问题标题】:How to get a sub collection with firestoreConnect in React-redux project - Cloud Firebase如何在 React-redux 项目中使用 firestoreConnect 获取子集合 - Cloud Firebase
【发布时间】:2021-02-27 13:11:40
【问题描述】:

我正在通过下面的教程学习 react-redux-firebase。

我在收藏中添加了子收藏。 但是,我不知道如何获取子集合。 我需要获取原始集合及其子集合。

教程: https://github.com/iamshaunjp/React-Redux-Firebase-App/blob/lesson-20/marioplan/src/components/projects/ProjectDetails.js

const mapStateToProps = (state, ownProps) => {
    const id = ownProps.match.params.id;
    const projects = state.firestore.data.projects;
    const project = projects ? projects[id] : null
    const subproject = //?
}

export default compose(
    connect(mapStateToProps),
    firestoreConnect([
        { collection: 'projects',
        collection: 'subprojects'
    }
    ])
)(ProjectDetails);

我想用这个

不是

【问题讨论】:

    标签: javascript reactjs google-cloud-firestore react-redux react-redux-firebase


    【解决方案1】:

    编辑答案:

    我没有在此处发布所有步骤,但您需要遵循与项目集合完全相同的步骤,但对于您的子项目集合,因此制作您的子项目减速器,将其添加到 rootReducer...等,以便子项目处于全局状态,您可以将它们链接到您的组件,就像您对项目集合所做的那样。

    您需要定义它是否在单独的减速器中,在项目减速器本身中,以便它处于如下状态:const subprojects = state.firestore.data.projects.subprojects;

    要编写您的连接器,您需要查看redux-firestore repo,它建议如何连接子集合。检查示例:

    {
      collection: 'cities',
      doc: 'SF',
      subcollections: [{ collection: 'zipcodes' }],
      storeAs: 'SF-zipcodes' // make sure to include this
    },
    

    也就是说,mapStateToProps 如下:

    const mapStateToProps = (state, ownProps) => {
      // console.log(state);
      const id = ownProps.match.params.id;
      const subprojects = state.firestore.data.projects.subprojects;
      const subproject = subproject ? subproject [id] : null
      return {
        subproject : subproject 
      }
    }
    
    export default compose(
      connect(mapStateToProps),
      firestoreConnect([{
        collection: 'projects',
        doc: 'YourDoc'
        subcollections: [{ collection: 'subprojects' }],
        storeAs: 'YorDoc-subprojects'
      }])
    )(YourSubProjectsComponent)
    

    没有调试过的代码,只是基于 repo 示例的建议,以防对您继续前进有帮助。

    另一方面,如果有任何帮助,请在projectDetails 组件的代码下方找到,使用useState 挂钩从firestore 中获取确定的项目。对于您的具体情况,我相信它会以相同的方式应用,但查询您的 subprojects 集合。 (打字稿代码)。我发布这个,以防万一您可能在“手动”获取您的集合之后,而不是直接与 redux 绑定。如果你想要的是直接绑定你的子项目集合的 redux,你可以省略下面的代码。

    import { IFirebaseProject } from '../../store/types/projectTypes';
    import { Redirect } from 'react-router-dom';
    import moment from 'moment';
    import firebase from 'firebase/app';
    import { useState } from 'react'; 
    
    async function getFbProject(id: string) {
      const db = firebase.firestore();
      const fbDoc = db.collection("projects").doc(id);
      let project = {} as IFirebaseProject;
      await fbDoc.get().then(function(doc) {
          if (doc.exists) {
              console.log("Document data:", doc.data());
              project = { ...doc.data()} as IFirebaseProject;
          } else {
              console.log(`Document does not exist ${id}`);
          }
      }).catch(function(error) {
          console.log(`Error getting document: ${id}`, error);
      });
    
      return project;
    }
    
    function getProjectId():string {
      const pathStr = window.location.pathname.toString();
      const parts = pathStr.split("/");
      const projStrIndex = parts.indexOf('project');
      const projectId = parts[projStrIndex + 1];
      return projectId;
    }
    
    const ProjectDetails = ({ project }: { project: IFirebaseProject } | { project: undefined }) => {
      const [stateProject, setStateProject] = useState<IFirebaseProject | undefined>(project);
      if (!firebase.auth().currentUser) return <Redirect to='/'/>
      if (stateProject) {
        return(
          <div className="container section project-details">
            <div className="card z-depth-0">
              <div className="card-content">
                <span className="card-title">{stateProject.title}</span>
                <p>
                  {stateProject.content}
                </p>
              </div>
              <div className="card-action grey lighten-4">
                <div>{stateProject.authorFirstName} {stateProject.authorLastName}</div>
                <div>{moment(stateProject.createdAt.toDate()).calendar()}</div>
              </div>
            </div>
          </div>
        )
      } else {
        //fetch project
        const projectId = getProjectId();
        getFbProject(projectId).then((project) => { 
          if (project) {
            setStateProject(project);
          }
        });
    
        return(
          <div>
            <p> Loading project... </p>
          </div>
        )
      }
    }
    
    export default ProjectDetails;
    

    【讨论】:

      猜你喜欢
      • 2019-05-26
      • 2019-10-06
      • 2021-02-13
      • 2019-06-23
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      相关资源
      最近更新 更多