Как получить все поля документа в подколлекции появляются одновременно - PullRequest
0 голосов
/ 26 марта 2020

Мне просто нужна помощь в получении поля документа в базе данных пожарного магазина. Образец изображения Образец изображения здесь по ссылке - это моя коллекция пользователя. Я пытался получить все поля документа «groupName» и заставить его отображаться на экране. С кодом, который я использую, на экране появляется только одно поле.

  class CreateNewGroup extends Component {
  constructor(props) {
     super(props);
     this.state = ({
       groupName: '',
       loading: false,

    });
  };

  getCoordinates(query) {
    console.log('start loading animation');
  };

 MountFSUserGroup = () => {
 const curUser = firebase.auth().currentUser;

 const dbUser =
  firebase
  .firestore()
  .collection('users')
  .doc(curUser.uid)
  .collection('SampleGroup') 
  .get()  
  .then(snapshot => {
     if (snapshot.empty) {
        console.log('No matching documents.');
        return;
     }  
     snapshot.forEach(doc => {
        console.log(doc.id, '=>', doc.data()); 
        const { groupName } = doc.data();
        this.setState({ groupName, loading: false }); 

     });
   })
   .catch(err => {
        console.log('Error getting documents', err);
   });  

  const { groupName } = dbUser;
  this.setState({ groupName, loading: true }); 
  };


  componentDidMount() {
    this.MountFSUserGroup()
  }; 

  UNSAFE_componentWillMount() {
    this.MountFSUserGroup()
    console.log("user group mounted");
  };      


  render() {

  return (
     <View style={{flex: 1,}}>
        <CustomHeaderBack />
        <Loader loading={this.state.loading} />

        <ScrollView>
        <View style={styles.body}>
              <View style={styles.titleCont}>
              <Text 
                 style={styles.text1}>
                    SAMPLE GROUP LIST
              </Text>         
              </View> 

              <View style={styles.insideCont}>
              <Text 
                 style={styles.text2}>
                    Select Your Group:
              </Text>


              <Text 
                 style={styles.text2}>
                    {this.state.groupName}

              </Text>


              </View>
        </View>
        </ScrollView>
        <CustomFooter />
     </View>    
     )
    }
    };

     export default CreateNewGroup ;

Пример экрана показывает только третье поле "groupName:" Group Three "" отображается, но на консоли (образец журнала консоли) все поля перечислены одновременно.

если я использую

  .where('groupName', "==", true)

, он переходит к пустому сообщению об ошибке «Нет соответствующего документа», и экран зависает. Надеюсь, кто-то может помочь. Заранее спасибо.

1 Ответ

0 голосов
/ 27 марта 2020

Есть пара проблем с кодом в его нынешнем виде.

this.setState({ groupName, loading: false }); - это установка только последнего обнаруженного groupName в состояние компонента. Что является оригинальной проблемой. Вам придется snapshot.map()

Если он постоянно рендерится, то этот fn, вероятно, где-то вызывается в цикле рендеринга. Как правило, всегда лучше максимально дифференцировать поиск данных и управление состоянием. Таким образом, если вы переместите getGroupNames в собственную функцию и предоставите идентификатор пользователя и экземпляр firebase, вы сможете установить значение в состояние, только если оно отличается от предыдущих значений.

Или, если вы используете хуки, которые я настоятельно рекомендую, если вы можете, тогда используйте useMemo или настройте вызов, используя useEffect в зависимости от идентификатора пользователя. В любом случае вызовы будут ограничены только при необходимости.

Что-то вроде этого подойдет?

//...imports...

class CreateNewGroup extends Component {
  constructor(props) {
     super(props);
     this.state = ({
       groupNames: [],
       loading: false,
    });
  };

//i might even take this out of the component and declare it as a pure js function
// as it is not using anything from 'this' and loading can be set where it is being called from too
 getFSUserGroup = async () => {
    try {
        this.setState({ loading: false })
        const curUser = firebase.auth().currentUser;

        // get some value
        const data = async firebase
            .firestore()
            .collection('users')
            .doc(curUser.uid)
            .collection('SampleGroup') 
            .get()  
            .map(doc =>  doc.data().groupName); // get all the group names for each item
        this.setState({ loading: false }) // set loading as false, will trigger a render
        return data // return that data from above
    } catch (e) {
        // failed to get documents
        this.setState({ loading: false })
    }// if it errored or something, it would return undefined
}


  componentDidMount() {
    this.getFSUserGroup().then(x => {
        if (x && !this.state.groupNames) {
            this.setState({ groupNames })
        }
        // it might not be a great idea to simply `!this.state.groupNames` though.. :(
    })


  }; 
// render and other stuff

Кроме того, если вы только начинаете ... это может быть хорошей идеей взглянуть на Реагировать на компоненты без состояния , потому что тогда вы можете использовать Крючки , которые, помимо прочего, аккуратно абстрагируют большую часть кода базовой платы, задействованного в выполнении простых задач, подобных той, которую вы выполняете , Для хорошего введения в почему и как взгляните на этот

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...