0
votes

I want to get all documents stored in firebase. If there are more than 0 documents, then render 1, otherwise print the no doc found but that gives me the error:

render() {
    firebase
      .firestore()
      .collection("users")
      .doc(localStorage.getItem("ph"))
      .collection("chat")
      .get()
      .then(d => {
        this.dt = d.docs.length;
        if (this.dt > 0) {
          return <div>1</div>;
        } else {
          return (
            <div>
              <div className="app-noFoundArea">
                <img src={noFound} />
              </div>
              <div className="app-noFound-title">
                <p>
                  No chat found. Try create using{" "}
                  <button className="app-add-icon app-nofound">
                    <i className="material-icons">add</i>
                  </button>
                </p>
              </div>
            </div>
          );
        }
      })
      .catch(e => {});
  }
3

3 Answers

1
votes

It's probably not a good idea to fetch the data in render, since that will happen every time your state or props update. It is also asynchronous, so nothing will actually be returned for React to render.

You are better off putting the firebase logic in componentDidMount:

class MyComponent extends React.Component {
  state = { loaded: false, docs: [] };

  componentDidMount() {
    firebase
      .firestore()
      .collection("users")
      .doc(localStorage.getItem("ph"))
      .collection("chat")
      .get()
      .then(d => {
        this.setState({ loaded: true, docs: d });
      })
      .catch(e => {
        this.setState({ loaded: true });
      });
  }

  render() {
    const { loaded, docs } = this.state;

    if (!loaded) {
      return null;
    }

    if (docs.length > 0) {
      return <div>1</div>;
    } else {
      return (
        <div>
          <div className="app-noFoundArea">
            <img src={noFound} />
          </div>
          <div className="app-noFound-title">
            <p>
              No chat found. Try create using{" "}
              <button className="app-add-icon app-nofound">
                <i className="material-icons">add</i>
              </button>
            </p>
          </div>
        </div>
      );
    }
  }
}
0
votes

You have to return the response made inside the firebase function.

render() {
return (
<div>
  {
    firebase.firestore().collection("users").doc(localStorage.getItem("ph")).collection("chat").get()
        .then((d) => {
            this.dt = d.docs.length;
            if (this.dt>0 ) {
              return (<div>1</div>)
            } else {
              return (
                <div>
                  <div className="app-noFoundArea">
                      <img src={noFound}></img>
                  </div>
                  <div className="app-noFound-title">
                      <p>No chat found. Try create using <button className="app-add-icon app-nofound"><i className="material-icons">add</i></button></p>
                  </div>
                </div>
            )
          }
      })
      .catch((e) => {
      })    
  }
</div>
 )
}
0
votes

You are mixing A component and JS code together where if it falls in catch function then it would not return anything.

The render method in React.Component always expect to return a valid HTML structure.

You can try with following modifications in your code

constructor(props) {
    super(props)
    this.state = {
     IsChatFound : false
    };
  }

  getChatInfo = () => {
   try{
        firebase.firestore().collection("users").doc(localStorage.getItem("ph")).collection("chat").get()
        .then((d) => {
            this.setState({IsChatFound :(d.docs && d.docs.length > 0)}); 
        });
    }
    catch(error){
      this.setState({IsChatFound : false}); 
    }
  }

  componentDidMount =()=>{
    this.getChatInfo();
  }


  render() {
    return (
        {this.state.IsChatFound ?
            <div>1</div>
        : <div>
            <div className="app-noFoundArea">
                <img src={noFound}></img>
            </div>
            <div className="app-noFound-title">
                <p>No chat found. Try create using <button className="app-add-icon app-nofound"><i className="material-icons">add</i></button></p>
            </div>
         </div>
        }
    )         
 }

You see now render() method always returns HTML