简体   繁体   中英

Getting an Empty array from the firestore

This is my code for LeftBar Component I want to get the data stored in the "contacts" document in the firebase but getting an empty array. Idk know why this is happening. And one thing if anyone can tell me how to do it with class-based component ( how to use that use effect thing into ComponentDidMount and ComponentDidUpdate) as I have two other class Components which are also using the same functionality Please help

import React, {useState , useEffect}  from "react";
import { Avatar, IconButton } from "@material-ui/core";
import AddCircleIcon from "@material-ui/icons/AddCircle";
import MoreIcon from "@material-ui/icons/More";
import ChatBubbleOutlineIcon from "@material-ui/icons/ChatBubbleOutline";
import SearchIcon from '@material-ui/icons/Search';
import LeftChats from './LeftChats';
import "./LeftBar.css";
import db from './firebase'

function LeftBar () {
  const [contacts, setContacts] = useState([])

  useEffect(() => {
    db.collection("contacts").onSnapshot((snapshot)=> setContacts(
      snapshot.docs.map((doc)=> ({
        id : doc.id,
        data : doc.data(),
      }))
    ))
  },[])
  
  console.log(contacts);

    return (
      <div className="leftbar">
        <div className="left-header">
          <Avatar />
          <div className="left-right-header">
            <IconButton>
            <AddCircleIcon />
            </IconButton>
            <IconButton>
            <MoreIcon />
            </IconButton>
            <IconButton>
            <ChatBubbleOutlineIcon />
            </IconButton>
          </div>
        </div>

        <div className="left-search">
            <div className='input-container'>
            <SearchIcon/>
            <input type='text' placeholder='Search...'/>
            </div>
        </div>
       

        <div className="left-chats">
{
              contacts.map( contact =>( 
                <LeftChats key={contact.id} id = {contact.id} username= 
                 {contact.data.name}/>
              ))
            }
          
        </div>
      </div>  
    );
  
}

export default LeftBar;

This is my LeftChat Component

import React, { Component } from 'react'
import { Avatar} from "@material-ui/core";


class LeftChats extends Component {
   constructor(props) {
       super(props)
   
       this.state = {
            data : ''
       }
   }
render() 
    {
        console.log(this.props)
        return  (
            <div className='leftchats'>
                <Avatar/>
                <div className='chats-info'>
                <h2>{this.props.username}</h2>
                <p>Some text message...</p>
                </div>
            </div>
        ) 
    }
}

export default LeftChats

Using

<LeftChats key={contact.id} id = {contact.id} username= 
                 {contact.data.name}/>

means that you are passing {contact.data.name} value to your custom LeftChats component. But your data prop is empty. Check your console to see whether you get data or not, since you've used console.log(this.props) inside <LeftChats /> . And for the sake of completness, you should import all from firebase, unless you know exactly what you'are doing:

import * as firebase from 'firebase';
import 'firebase/firestore';

Then have these configuration set appropriately:

const firebaseConfig = {
    apiKey: "AIsdfghjzaSyC0ZHz8ooSoi05Vt2X7UL7qV9Aga1o", // use your own
    authDomain: "dj-himmels.firebaseapp.com",
    databaseURL: "https://dj-himmels.firebaseio.com",
    projectId: "dj.himmels",
    storageBucket: "dj-himmels.appspot.com",
    messagingSenderId: "285437504174",
    appId: "1:285566504174:web:0a9ttgb4a968acd08f7ff"
  };

which is missing from your code.

In a real react native app for production, you should be using AsyncStorage to proceed your data.

Note: For your next questions try to ask one question at a time, it helps to figure out your real need and answer it accordingly. Right now you seem to be having many issues.

EDITED AFTER THE POSTER COMMENT

1- First of all, you are passing {contact.data.name} to username instead of {contacts.data.name} , because you used React hook useState to define contacts as const [contacts, setContacts] = useState([]) and not as const [contact, setContact] = useState([]) 2- Second of all, if at all the

<LeftChats key={contact.id} id = {contact.id} username= 
                 {contact.data.name}/> 

component found the {contacts.data.name}, value to pass to username= contacts.data.name} , you will still get empty result because using useState([]) inside const [contacts, setContacts] = useState([]) means that you have set Contact value to empty array. Nevertheless, you have tried to send value to Contact using React

useEffect hook like so useEffect(() => {
    db.collection("contacts").onSnapshot((snapshot)=> setContacts(
      snapshot.docs.map((doc)=> ({
        id : doc.id,
        data : doc.data(),
      }))
    ))
  },[]),

which was not triggered before component receives the initial empty array of contact . And your data value fetched from firebase may also be empty, that's why I meant by you are having many issues in the same time.

MY SUGGESTION: 1- Console.log the doc value to check whether it is empty or not. If so, then the problem is in the snapshot.docs.map((doc) otherwise it may be in the empty data inside the

this.state = {
                data : ''
           } 

I make suggestions because I don't really know your real architecture. Also take a look at the react useEffect hooks here You may need to set a conditional value inside the [] of your

useEffect(() => {
   
  },[x])

to reset Contact after that condition. Ultimately remember that there is still a great amount of value in sticking with functional components rather than going back to the class based components. Hope it help !

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