0

Programmes.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;

As can be seen from the codes above, I am able to get the documents from the two collections. What I would like to do is to get the values of ProgrammeName and filter the available FacultyName from my selected value of ProgrammeName, after which I will select a value from FacultyName and be directed to the Courses screen which will be filtered by the values of ProgrammeName and FacultyName that I have chosen. What would be an ideal way to filter them based on what I have selected?

1 Answers1

0

As indicated in this other answer here, using a structure of database as you are using is not very good. Using this way, you will need to perform two queries - as you are already doing - which will cost you more. If you change your database just a bit, it could make it easier. In this case, if you added the ProgrammeName as a field of FacultyName, it would be easier and less costly for you. A code to return values with a structure as data would be the following:

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

In case this change of database is not possible, you can give it a try using the below code, to return values based in one another.

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));

This code sample is based in this post here that I believe it's very similar to yours.

While this code is untested, I believe it's good starting point for you to give. And to remember, I would recommend you to combine the collections, so you don't have double costs and more complex queries.

Let me know if the information helped you!

gso_gabriel
  • 4,199
  • 1
  • 10
  • 22
  • I took your suggestion on integrating ProgrammeName as a field of FacultyName and it did indeed make things so much easier. Thanks for the help! – user3044463 May 17 '20 at 12:53
  • Hi @user3044463 I'm glad to hear that. Please, consider accepting / upvoting my answer, since it helped you. :) – gso_gabriel May 18 '20 at 05:27