Subhodeep bhowmick
Subhodeep bhowmick

Reputation: 99

Display data in react native component | Firebase

I am new to react native and was trying to display some data into a react component (preferably cards) but for now FlatList will work. I was unable to destructure the data and display it. How should it be done?

import React,{useState,useEffect} from 'react';
import { StyleSheet,Modal,  View ,Text , ScrollView, Alert} from 'react-native';
import {IconButton ,Appbar, Card,  TextInput ,Button ,
  } from 'react-native-paper';
  import firebase from './config';
  import { LogBox } from 'react-native';
  LogBox.ignoreLogs(['Setting a timer']);

export default function PlantATree(){
  const [modalVisible, setModalVisible] = useState(false);
  
  const [name,setName]=useState('');
  const [title, setTitle]=useState('');
  const [description, setDescription]=useState('');
  const [data, setmyData]=useState([])

  const savePost =  () =>{
       
      firebase.database()
      .ref('posts')
      .push({
        "id":Math.random(),
        "name":name,
        "title":title,
        "description":description,
        
      })
    setTimeout(()=>{
      Alert.alert("Your post is saved successfully :D")
    },1000)

  }

    useEffect(()=>{
      const data = firebase.database().ref("posts");
      data.on("value", datasnap =>{
        //console.log(Object.values(datasnap.val()));
        if(datasnap.val()){
        setmyData(datasnap.val());
        }
      })
    },[]);
    //console.log(data);
    const src= Object.keys(data);
    console.log("Hi",src);
  return (
    <ScrollView>
       <Appbar.Header>
            <Appbar.Content title="Plant a tree Initiative"/>
        </Appbar.Header>
        <IconButton
          icon="plus"
          color="crimson"
          size={30}
          onPress={() => setModalVisible(true)}
        />
      <View style={styles.centeredView}>
              {/*Modal Content Starts Here*/}
                <Modal
                  animationType="slide"
                  transparent={true}
                  visible={modalVisible}
                  >

                  <View style={styles.centeredView}>
                    <ScrollView style={styles.modalView}>
                      
                    <Appbar.Header style={{ padding:10}}>
                        <Appbar.Content title="Share your story.." />
                    </Appbar.Header>
                      <Card>
                        <Card.Content >
                          <View style={{marginLeft:0,marginRight:0,
                          }}>
                          <Card >
                         <Card.Content>
                          <TextInput
                            style={{}}
                            label="Your name...."   
                            mode="outlined"
                            value={name}
                            onChangeText={text =>{ setName(text)}} 
                          />
                          <TextInput
                            style={{}}
                            label="Story Title...."   
                            mode="outlined" 
                            value={title}
                            onChangeText={text =>{ setTitle(text)}}
                          />
                          <TextInput
                            style={styles.formcomponents}
                            label="Share your thoughts...."   
                            mode="outlined"
                            multiline={true}
                            numberOfLines={8}
                            value={description}
                            onChangeText={text =>{ setDescription(text)}}
                          
                          />
                          </Card.Content>
                          </Card>
                            </View>
                            <Card>                            
                                <Button mode="contained" style={{margin:20}} 
                                onPress={savePost}>
                                          post
                                </Button>
                                <Button mode="contained" style={{margin:20,backgroundColor:'crimson'}} onPress={() => setModalVisible(!modalVisible)}>
                                          close
                                </Button>
                            </Card>
                        </Card.Content>
                      </Card>
                    </ScrollView>
                  </View>
                </Modal>  
          </View>
    <View>
                  {/* DATA FROM FIREBASE  */}

                  <Text>{data?.description}</Text>
    </View>
  
    </ScrollView>
  )
}


  
const styles = StyleSheet.create({
  centeredView: {
      
    marginTop: 45,
    marginBottom:45,
  },

  modalView: {
    backgroundColor: "white",
    borderRadius: 20,
    
    marginTop:70,
    marginBottom:20,
    marginRight:20,
    marginLeft:20,
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5
    },
  openButton: {
    backgroundColor: "#F194FF",
    borderRadius: 20,
    padding: 10,
    elevation: 2
  },
  textStyle: {
    color: "white",
    fontWeight: "bold",
    textAlign: "center"
  },
});

Data Format:

Object {
  "-MQXpKu8Zh1PCVsBLquO": Object {
    "description": "Good story.",
    "id": 0.8842625745597491,
    "name": "Subhodeep",
    "title": "Story 1 ",
  },
  "-MQXpRXS5_6m6YTZ39e0": Object {
    "description": "Good story 2.",
    "id": 0.8767685757714464,
    "name": "Sanjoy",
    "title": "Story 2",
  },
  "-MQXpX7ku-41CreQ8SOP": Object {
    "description": "Good story 3.
",
    "id": 0.9976208307830834,
    "name": "Sanchari",
    "title": "Story 3",
  },

This is my data format

Upvotes: 0

Views: 589

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598668

Since the data from Firebase consists of multiple nodes, you'll need to iterate over the results and map each child to a new component.

I typically find that easiest by first converting the snapshot to an array (instead of an Object) when it is loaded:

useEffect(()=>{
  const data = firebase.database().ref("posts");
  data.on("value", datasnap =>{
    let data = [];
    datasnap.forEach((childsnap) => {
      let val = childsnap.val();
      val["$key"] = childsnap.key;
      data.push(val);
    })
    setmyData(data);
  })
},[]);

Then in the rendering code we can loop over this data array and render a component for each item:

data.map((item) => <Text id={item["$key"]}>{item.description}</Text>)

There might be some syntax errors in the rendering, but the overall flow should be clear from this.

Upvotes: 1

Related Questions