3

I am having 2 problems using React Native and Firebase Real Time Database.

  • When I add something to the list with the text input, all the list itens are duplicated except the item that I just added, this problem is only solved when I refresh the app screen.

  • When I remove something from firebase dashboard or other client, the list is not updated real time.

  import React, {useState, Component} from 'react';
  import {
    Text,
    View,
    Switch,
    StyleSheet,
    FlatList,
    TextInput,
    Button,
    TouchableOpacity,
    SafeAreaView,
    VirtualizedList,
  } from 'react-native';

  import database from '@react-native-firebase/database';

  class MenuBreakFastScreen extends React.Component {
    state = {newItem: ''};
    state = {itens: []};

    componentDidMount() {
      let dbRef = database().ref('/cafe/itens/');
      this.listenerFirebase(dbRef);
    }

    listenerFirebase(dbRef) { 
      dbRef.on('value', dataSnapshot => {
        const newItens = JSON.parse(JSON.stringify(this.state.itens));
        dataSnapshot.forEach(child => {
          newItens.push({
            name: child.val().name,
            key: child.key,
          });
          this.setState({itens:newItens});
        });
      });
    }

    addItem() {
      if (this.state.newItem === '') {
        return;
      }
      database().ref('/cafe/itens/').push({
        name: this.state.newItem,
      });
      this.setState({
        newItem: '',
      });
    }

    render() {
      const {itens} = this.state;
      const {newItem} = this.state;
      const renderItem = ( {item}) => {
        return(
          <ItemAsset title={item.name}/>
        );
      }
      return (
        <SafeAreaView
          style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
          <FlatList 
          data={itens}
          renderItem={renderItem}
          keyExtractor={item => item.key}
          />
          <SafeAreaView style={{flexDirection: 'row'}}>
            <TextInput
              style={styles.input}
              onChangeText={text =>
                this.setState({
                  newItem: text,
                })
              }
              value={newItem}
            />
            <TouchableOpacity style={styles.Botao} onPress={() => this.addItem()}>
              <Text style={styles.BotaoTexto}>+</Text>
            </TouchableOpacity>
          </SafeAreaView>
        </SafeAreaView>
      );
    }
  }

  const styles = StyleSheet.create({
    texto: {
      fontSize: 35,
    },
    input: {
      color: '#000',
      fontSize: 22,
      borderWidth: 1,
      flex: 8,
      margin: 10,
    },
    BotaoTexto: {
      color: '#fff',
      fontSize: 22,
    },
    Botao: {
      backgroundColor: '#000',
      marginTop: 10,
      padding: 10,
      flex: 1,
      alignItems: 'center',
      margin: 10,
    },
    ListaContainer: {
      flexDirection: 'row',
      backgroundColor: '#000',
      flex: 1,
    },
    item: {
      backgroundColor: '#000',
      padding: 20,
      marginVertical: 8,
      marginHorizontal: 16,
      flexDirection: 'row',
    },
    title: {
      color: '#ffff',
      fontSize: 32,
    }, 
  });

  const ItemAsset = ( {title} ) => {
    return(
      <View style={styles.item}>
        <Text style={styles.title}>{title}</Text>
      </View>
    );
  }
  export default MenuBreakFastScreen;

Reis
  • 101
  • 2
  • 7

1 Answers1

4

When you are listen for real time changes on real-time database it will send all the items with snapshot when any data is changed. That happens because you are listen for whole list, not only for a single item. Therefore you do not need to get the current list from state. You just have to set the state with retrieved data.

   listenerFirebase(dbRef) { 
      dbRef.on('value', dataSnapshot => {
        const newItens = [];         // This should be initially empty array. That's all.
        dataSnapshot.forEach(child => {
          newItens.push({
            name: child.val().name,
            key: child.key,
          });
        });
        this.setState({itens:newItens});
      });
    }

After correcting this part the error you got when removing data will be also resolved.

samthecodingman
  • 23,122
  • 4
  • 30
  • 54
Nimna Perera
  • 1,015
  • 10
  • 16