1

I am currently experiencing some issues with Firebase and the use of state. And yes, I would like to point out that I am new to React. Basically what I am trying to achieve, is to display all inquiries that have been sent to me, which are stored in firebase.

In an attempt to accomplish this, I have done as following:

constructor(props) {
  super();

  this.fetchMessage = this.fetchMessage.bind(this);
  this.state = {
    messages: []
  };
}

fetchMessage = () => {
  const database = firebase.database();
  const inquiries = [];

  database.ref('inquiries').on('value', (snapshot) => {
    snapshot.forEach((childSnapshot) => {
      inquiries.push({
        id: childSnapshot.key,
        fullName: childSnapshot.val().fullName,
        email: childSnapshot.val().email,
        message: childSnapshot.val().message,
        subject: childSnapshot.val().subject,
        dateSent: childSnapshot.val().dateSent
      });
    });
    console.log(inquiries);
    this.setState(() => {
      return {
        messages: inquiries
      }
    });
  });
}

What I am trying to do is to store all inquiries in state so that I can run a for-loop and display all of the content on my website. How exactly would I do this?

My first idea was to, as said: store each object in state, and then access each inquiry like this this.state.messages[0], this.state.messages[1] (to get the full array), and then display each value by doing this.state.messages[0].fullName for instance.

How can I achieve this? My current error is:

[Error] Invariant Violation: Objects are not valid as a React child (found: object with keys {id, fullName, email, message, subject, dateSent}). If you meant to render a collection of children, use an array instead.
    in h1 (created by AdminPanel)
    in div (created by AdminPanel)
    in AdminPanel (created by Route)
    in Route
    in Switch
    in div
    in Router (created by BrowserRouter)
    in BrowserRouter
    (anonymous function) (bundle.js:1530)
3
  • Have you tried 'this.setState({messages : inquiries});' instead? Commented Jan 6, 2018 at 11:08
  • @Dream_Cap still the same problem.. Strange.. Commented Jan 6, 2018 at 11:13
  • Can you add your code that renders the message list. Based on your error I'm guessing that's where it is Commented Jan 6, 2018 at 11:17

1 Answer 1

2

It seems the problem is not with your state but with your render method.

This is the way you should be doing to show the messages in your app.

componentDidMount() {
  this.fetchMessage()
}
render() {
  const { messages } = this.state
  return (
    <div>
      <table>
        {messages.map((message) => {
          return (
            <tr key={message.id}>
              <td>{message.fullName}</td>
              <td>{message.email}</td>
              <td>{message.message}</td>
              <td>{message.subject}</td>
              <td>{message.dateSent}</td>
            </tr>
          )
        })}
      </table>
    </div>
  )
}
Sign up to request clarification or add additional context in comments.

7 Comments

This gave me +999 errors when I used the code above. Strange error, do you know what may be the problem here?
How are you calling fetchMessage?
I am actually calling it in the render, above const { messages } = this.state, doing this: 'this.fetchMessage();'. I suppose this is wrong?
Yep, as a general rulo you don't have to call setState in render method never. Because it generates an infinite loop. Check out my answer I updated it.
This is awesome! It worked! Do you know how I can automate it, so I don't have to click a button?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.