【问题标题】:Passing values from firebase collections to filter documents from another collection传递来自 firebase 集合的值以过滤来自另一个集合的文档
【发布时间】:2020-08-31 19:20:30
【问题描述】:

程序.js

import React, { Component } from 'react';
import { StyleSheet, ScrollView, ActivityIndicator, View } from 'react-native';
import { ListItem } from 'react-native-elements'
import firebase from '../database/firebaseDb';

class Programmes extends Component {

  constructor() {
    super();
    this.firestoreRef = firebase.firestore().collection('Programmes');
    this.state = {
      isLoading: true,
      userArr: []
    };
  }

  componentDidMount() {
    this.unsubscribe = this.firestoreRef.onSnapshot(this.getCollection);
  }

  componentWillUnmount(){
    this.unsubscribe();
  }

  getCollection = (querySnapshot) => {
    const prgArr = [];
    querySnapshot.forEach((res) => {
      const { ProgrammeName } = res.data();
      prgArr.push({
        key: res.id,
        res,
        ProgrammeName
      });
    });
    this.setState({
      prgArr,
      isLoading: false,
   });
  }

  render() {
    if(this.state.isLoading){
      return(
        <View style={styles.preloader}>
          <ActivityIndicator size="large" color="#9E9E9E"/>
        </View>
      )
    }    
    return (
      <ScrollView style={styles.container}>
          {
            this.state.prgArr.map((item, i) => {
              return (
                <ListItem
                  key={i}
                  chevron
                  bottomDivider
                  title={item.ProgrammeName}
                  onPress={() => {
                    this.props.navigation.navigate('Faculties', {
                      userkey: item.key
                    });
                  }}/>
              );
            })
          }
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingBottom: 22
  },
  preloader: {
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    position: 'absolute',
    alignItems: 'center',
    justifyContent: 'center'
  }
})

export default Programmes;

Faculties.js

import React, { Component } from 'react';
import { StyleSheet, ScrollView, ActivityIndicator, View } from 'react-native';
import { ListItem } from 'react-native-elements'
import firebase from '../database/firebaseDb';

class Faculties extends Component {

  constructor() {
    super();
    this.firestoreRef = firebase.firestore().collection('Faculties');
    this.state = {
      isLoading: true,
      userArr: []
    };
  }

  componentDidMount() {
    this.unsubscribe = this.firestoreRef.onSnapshot(this.getCollection);
  }

  componentWillUnmount(){
    this.unsubscribe();
  }

  getCollection = (querySnapshot) => {
    const facArr = [];
    querySnapshot.forEach((res) => {
      const { FacultyName } = res.data();
      facArr.push({
        key: res.id,
        res,
        FacultyName
      });
    });
    this.setState({
      facArr,
      isLoading: false,
   });
  }

  render() {
    if(this.state.isLoading){
      return(
        <View style={styles.preloader}>
          <ActivityIndicator size="large" color="#9E9E9E"/>
        </View>
      )
    }    
    return (
      <ScrollView style={styles.container}>
          {
            this.state.facArr.map((item, i) => {
              return (
                <ListItem
                  key={i}
                  chevron
                  bottomDivider
                  title={item.FacultyName}
                  onPress={() => {
                    this.props.navigation.navigate('Courses', {
                      userkey: item.key
                    });
                  }}/>
              );
            })
          }
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingBottom: 22
  },
  preloader: {
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    position: 'absolute',
    alignItems: 'center',
    justifyContent: 'center'
  }
})

export default Faculties;

从上面的代码可以看出,我能够从两个集合中获取文档。 我想做的是获取 ProgrammeName 的值并从我选择的 ProgrammeName 值中过滤可用的 FacultyName,之后我将从 FacultyName 中选择一个值并被引导到 Courses 屏幕,该屏幕将由 ProgrammeName 的值过滤和我选择的 FacultyName。根据我选择的内容过滤它们的理想方法是什么?

【问题讨论】:

    标签: firebase react-native google-cloud-firestore


    【解决方案1】:

    正如另一个答案here 中所指出的,使用您正在使用的数据库结构并不是很好。使用这种方式,您将需要执行两个查询 - 正如您已经在做的那样 - 这将花费您更多。如果你稍微改变一下你的数据库,它会变得更容易。在这种情况下,如果您将ProgrammeName 添加为FacultyName 的字段,对您来说会更容易且成本更低。将具有结构的值作为数据返回的代码如下:

    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    CollectionReference productsRef = rootRef.collection("FacultyName");
    Query query = productsRef.whereArrayContains("ProgrammeName", "<Name>");
    

    如果无法对数据库进行这种更改,您可以使用以下代码尝试一下,以相互返回值。

    this.feedCollection = this.afs.collection('ProgrammeName');
    this.feedItem = this.feedCollection.snapshotChanges().map(changes => {
          return changes.map(a => {
            const data = a.payload.doc.data() as Feed;
            const resId = data.res_id;
            return afs.collection('FacultyName').doc(resId).snapshotChanges().take(1).map(actions => {
              return actions.payload.data();
            }).map(res => {
              return { firstName: res.firstName, ...data };
            });
          })
        }).flatMap(feeds => Observable.combineLatest(feeds));
    

    此代码示例基于此帖子here,我相信它与您的非常相似。

    虽然此代码未经测试,但我相信它是您提供的一个很好的起点。请记住,我建议您将这些集合组合起来,这样您就不会产生双重成本和更复杂的查询。

    如果这些信息对您有帮助,请告诉我!

    【讨论】:

    • 我采纳了您关于将 ProgrammeName 集成为 FacultyName 字段的建议,它确实让事情变得容易多了。感谢您的帮助!
    • 嗨@user3044463 我很高兴听到这个消息。请考虑接受/支持我的回答,因为它对您有所帮助。 :)
    猜你喜欢
    • 2015-06-12
    • 1970-01-01
    • 2017-10-17
    • 2012-08-27
    • 1970-01-01
    • 2016-08-19
    • 2022-01-09
    • 1970-01-01
    • 2021-04-19
    相关资源
    最近更新 更多