简体   繁体   中英

How to get a single doc info from firebase?

function AccountPage() {

    const [{ patients, user }, dispatch] = useStateValue();
    
    var therapist = '';

    db.collection('therapists').doc(user.uid).get().then((snapshot) => {
        therapist = snapshot.data()
        console.log(therapist)
      })

    useEffect(() => {
        console.log(therapist)
        var allService = therapist.service.service[0].label
    
        for (let i = 1; i < therapist.service.service.length; i++) {
            allService += ', ' + therapist.service.service[i].label;
        }
    
        var allLanguages = therapist.language.language[0].label
    
        for (let i = 1; i < therapist.language.language.length; i++) {
            allLanguages += ', ' + therapist.language.language[i].label;
        }
    }, [])

I'm trying to read a document in the firebase collection. I can read it and display to console, but for some reason I am not able to save the data. If I try to use therapist variable later in the code, it is undefined. I tried using useState, but it does the same thing, where therapist is undefined. I really don't get it.

在此处输入图像描述

Tried using useState, with or without therapist in UseEffect, without useEffect

Something to keep in mind with React components is that their render methods are to be considered pure, synchronous functions. The entire body of a React function component is the render "method". Each time AccountPage is rendered is declares therapist = "" , and then an unintentional side-effect to collect the firebase document is kicked off. The useEffect hook runs after the component has rendered and tries to read properties of the empty string value that is therapist and throws the error.

therapist should be part of the React state so that it can be updated and trigger a rerender with the fetched data. The firebase document should be fetched as an intentional side-effect via a useEffect hook.

function AccountPage() {
  const [{ patients, user }, dispatch] = useStateValue();
    
  const [therapist, setTherapist] = React.useState();

  // Fetch therapists document for specific user
  useEffect(() => {
    if (user.uid) {
      db.collection('therapists').doc(user.uid).get()
        .then((snapshot) => {
          setTherapist(snapshot.data());
        });
    }
  }, [user]);

  // Compute services and languages when therapist state updates
  useEffect(() => {
    console.log(therapist);

    const allService = therapist?.service?.service
      .map(({ label }) => label)
      .join(", ");
    const allLanguages = therapist?.language?.language
      .map(({ label }) => label)
      .join(", ");

    ...

  }, [therapist]);

  ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM