FlatList does not render data when launching the application-Firebase integration

Good Afternoon folks, I was studying the React Native Firebase library in order to learn how to work with a Firebase integration with React Native. However, I am facing some problems, the goal is to add the data in the Realtime Database through a screen and then take the data stored in the database to present on the Home screen using a FlatList (something that should be simple), but the big problem is that the application does not render the data already stored when it is opened for the first time, i.e. when you start the App. The data is rendered by FlatList only when I navigate to the Add screen and add a new item in the database (so it renders the newly added and the existing ones) or when I perform a "Refresh" in the App (giving a CTRL+S in the IDE or reloading the App in the emulator). In an attempt to solve the problem I did some tests and from what I noticed The FlatList takes the data stored in the state when it is still empty, i.e. has not received firebase data yet, even if it has already made the request . I tried to use asynchronous functions to try to solve, but without success, so I decided to resort to you, I will make available the most basic code I did (which in my design should work). I already ran the App on my physical device, believing it was an emulator problem, but the problem persisted. Follow the code originally used:

import React, { useState } from 'react';  
import styled from 'styled-components/native';

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

const Container = styled.SafeAreaView`
    flex:1;
    justify-content:center;
`;

const Texto = styled.Text`
    margin:20px;
`;

const Lista = styled.FlatList``;

const Botao = styled.Button`

`;

const HomeScreen = (props) => {

    const [vetor, setVetor] = useState([])

    database().ref('users').on('value', (snapshot) => {

        snapshot.forEach((childItem)=>{

            vetor.push({
                name:childItem.val().name,
                idade:childItem.val().idade
            })
        })

        setVetor(vetor)
    })

    const mudarTela = () => {
        props.navigation.reset({
            routes:[{name:'Tela2'}]
        })
    }

    return (
        <Container>
           <Lista data={vetor} renderItem={({item})=><Texto>{item.name} idade: {item.idade}</Texto>}/>
            <Botao title='Tela de Adição' onPress={()=>mudarTela()} />
        </Container>
    );
}

export default HomeScreen;

It should be noted that I am new to the FrameWork and this is one of my first posts here, so forgive any mistake I have made.

Author: Alan Almeida, 2020-05-06

1 answers

Has a problem in your code, I don't know if it will solve the problem:

The state vetor is immutable, and should only be modified by the function setVetor. You are giving a push in vetor which seems to have no effect.

In this sense, create a temporary variable to store the result, and then update the result at the end. Something like this,

database()
  .ref('users')
  .on('value', (snapshot) => {
    const data = [];
    snapshot.forEach((childItem) => {
      data.push({
        name: childItem.val().name,
        idade: childItem.val().idade,
      });
    });

    setVetor(data);
  });

 0
Author: Pedro Henrique, 2020-05-12 02:55:42