Paso a paso como crear un CRUD con React y Firebase

Tecnología
    10 Noviembre, 2019   Regresar el blog
Compartir:

En el día de hoy vamos a crear el típico CRUD (Empleados) con tecnología front React.js  y backend con Firebase, una base de datos en tiempo real, gratuita.


Para empezar ingresamos a la web oficial de Firebase https://firebase.google.com/   para empezar a utilizar de las bases de datos en tiempo real solo es necesario tu cuenta de Gmail.


Vamos a Ir a consola > Agregar Proyecto > Introduce el nombre de tu proyecto >  Crear Proyecto > Continuar

Agregar Firebase a tu app

Firebase React


Ingresa el nombre de la App

Seguido te mostrará un script que iremos a utilizar mas adelante. 



Del script que nos han dado nada mas vamos a utilizar esta parte 

https://tupaginaonline.net/archivos/arc15_56_26.png


Copiala en algún block de notas que lo vamos a utiliza mas tarde.


Requisitos para empezar: 


Tener Node >= 8.10 y npm >= 5.6 instalados en tu máquina


Vamos a empezar con abrir la terminal [Tecla Window + R] y escribir lo siguiente:


cd desktop
npx create-react-app my-app


Esto tomará algo de tiempo una vez ya este listo procedemos a abrir nuestro editor de código favorito, en mi caso estaré utilizando Visual Studio Code


Adicionalmente vamos a instalar algunos módulos que necesitamos: firebase y materialize que lo vamos a usar como framework css


npm i firebase @material-ui/core


Bueno con esto estamos listos para empezar a codear.

Vamos a la carpeta Public y dejamos nada mas el index.html que lo dejaremos de esta manera:



<!DOCTYPE html>
<html lang="en">
<head> 
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
  <l ink rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" />
  <l ink rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
  <title>CRUD ReactJs y Firebase :: TupaginaOnline</title>
</head>
<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
</body>
</html>

Dentro de src/

Editamos el archivo index.js y lo dejaremos de esta manera:


import React from ´react´;
import ReactDOM from ´react-dom´;
import App from ´./App´;
 
ReactDOM.render(<App />, document.getElementById(´root´));


Ahora Abrimos el archivo App.js y lo dejamos así:



import React from ´react´;
import ´./App.css´;
import { 

BrowserRouter as Router, Route } from ´react-router-dom´;
import Home from 

´./components/Home´
import Header 

from ´./components/Header´

function App() {
  return (

    <Router>
       <Header />
      <Route exact path="/" component={Home} />
    </Router>

  );
}

export default App;


Crearemos una carpeta dentro de src/ llamada components 

dentro de components creamos 3 archivos llamados:

- DataRecords.js

-Header.js

-Home.js


Abrimos Header.js y escribiremos lo siguiente:



import React from ´react´;
import { makeStyles } from ´@material-ui/core/styles´;
import AppBar from 

´@material-ui/core/AppBar´;
import Toolbar from ´@material-ui/core/Toolbar´;
import Typography from 

´@material-ui/core/Typography´;

const useStyles = makeStyles({
  root: {
    flexGrow: 1,
  },
});

export default 

function SimpleAppBar() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
    

  <AppBar position="static" color="default">
        <Toolbar>
          <Typography 

variant="h6" color="inherit">
            CRUD ReactJs y Firebase :: TupaginaOnline
          

</Typography>
        </Toolbar>
      </AppBar>
    </div>
  );
}	


Ahora es el turno de Home.js:


Vamos primero con las importaciones:

import React from ´react´;
import Grid from ´@material-ui/core/Grid´;
import Typography from ´@material-ui/core/Typography´;
import 

TextField from ´@material-ui/core/TextField´;
import FormControlLabel from ´@material-

ui/core/FormControlLabel´;
import Checkbox from ´@material-ui/core/Checkbox´;
import Container from 

´@material-ui/core/Container´;
import Button from ´@material-ui/core/Button´;
import Dialog from ´@material-

ui/core/Dialog´;
import DialogActions from ´@material-ui/core/DialogActions´;
import DialogTitle from 

´@material-ui/core/DialogTitle´;
import InputLabel from ´@material-ui/core/InputLabel´;
import MenuItem from 

´@material-ui/core/MenuItem´;
import Select from ´@material-ui/core/Select´;
import Radio from ´@material-

ui/core/Radio´;
import RadioGroup from ´@material-ui/core/RadioGroup´;
import FormControl from ´@material-

ui/core/FormControl´;
import FormLabel from ´@material-ui/core/FormLabel´;
import DataRecords from 

´./DataRecords´
import * as firebase from "firebase/app";
import "firebase/database";

Te recuerdas que copiaras parte del script que nos había dado firebase?, es momento de usarlo acá


var firebaseConfig = {
apiKey: "AIzaSy***********",
authDomain: "formreactjsfirebase.firebaseapp.com",
databaseURL: 

"https://formreactjsfirebase.firebaseio.com",
projectId: "formreactjsfirebase",
storageBucket: "",
messagingSenderId: "859733713828",
appId: "1:859733713828:web:28d02708c92a94ac"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);


Creamos la clase con el siguiente contenido:

class Home extends React.Component {

state = {

        

employee: 

{
          id: ´´,
                basic: {
                name: ´´,
                email: ´´, 
address: 

´´,
                phone: ´´,
                gender: ´´,
                birthdate: ´´
       

     },
 

         

  job: {
                title: ´´,
                salary: ´´
            },
            

status: false
 

       

},

        employees: [],
        open: false,
        setOpen: false,
        nodata: 

false,
        

titleButton: ´Guardar´
    }

    componentDidMount() {
        this.cargarData();
    }

    

cargarData() {

        

firebase.database().ref(´frm01/´).on(´value´, snapshot => {
            const data = 

snapshot.val();

       

     if (data != null) {
                this.setState({ employees: data });
            

} else {
              

  this.setState({ nodata: true });
            }
        });

    }


    onSubmit = (e) 

=> {
        

e.preventDefault();

        const { employee } = this.state;

        const id = employee.id === 

´´ ? 

this.state.employees.length :  employee.id;

     
            var newEmployee = {
                

employee: {
   

                 basic: {
                        name: employee.basic.name,
                    

    email: 

employee.basic.email,
                        address: employee.basic.address,
                     

   phone: 

employee.basic.phone,
                        gender: employee.basic.gender,
                        

birthdate: employee.basic.birthdate
                    },
                    job: {
                        

title: employee.job.title,
                        salary: employee.job.salary
                    },
          

          id,
                    status: employee.status
                }
            }
        


        

firebase.database().ref(´frm01/´ + newEmployee.employee.id).set(newEmployee);

        this.setState(prevState 

=> ({ open: true, setOpen: true, nodata: false, titleButton: ´Guardar´, employee: { 

...prevState.employee, id: ´´  , basic: { ...prevState.employee.basic, name: ´´, phone: ´´, birthdate: ´´, 

email: ´´, gender: ´´, address: ´´ }, job: { ...prevState.employee.job,  title: ´´, salary: ´´   } } }))


    

}


    handleDelete = (id) => {

        firebase.database().ref(´frm01/´ + id).remove();
        

this.setState({ setOpen: true, open: true });

    }

    handleEdit = (id) => {

        firebase.database

().ref(´frm01/´ + id).on(´value´, snapshot => {
            const data = snapshot.val();

            

this.setState({ employee: data.employee, titleButton: ´Editar´ });

        });


    }


    onChange = (e) => {
 

       const { name, value } = e.target;
        this.setState({ employee: { ...this.state.employee, basic: { 

...this.state.employee.basic, [name]: value } } });
    }


    onChangeJob = (e) => {
        const { name, 

value } = e.target;


        this.setState({ employee: { ...this.state.employee, job: { 

...this.state.employee.job, [name]: value } } });



    }

    handleClose = () => {

        this.setState({ 

open: false, setOpen: false });
    }


    createYears = () => {

        let table = [];let options = [];
     

   for (let i = 1945 ; i< 2020 ; i++){
            options.push(`<MenuItem value="${i}">${i}

</MenuItem>`);
        }
        table.push(options);

        //console.log(table);
        return table;

  

  }

    render() {
        return (
            <React.Fragment>
                <Container 

maxWidth="lg" style={{ paddingTop: "50px" }}>
                    <Grid container spacing={3}>

       

                 <Grid item xs={12} sm={6} >
                            <Typography variant="h6" 

gutterBottom>
                                Rellene los campos
        </Typography>
                

            <form onSubmit={this.onSubmit}>
                                <Grid container 

spacing={3}>

                                    <Grid item xs={12} sm={12}>
                         

               <TextField onChange={this.onChange}
                                            required
    

                                        id="name"
                                            name="name"
     

                                       label="Nombre Completo"
                                            

fullWidth
                                            value={this.state.employee.basic.name}
                  

                      />
                                    </Grid>


                                 

   <Grid item xs={12} sm={6}>
                                        <TextField onChange=

{this.onChange}
                                            required
                                          

  id="email"
                                            name="email"
                                         

   label="Email"
                                            type="email"
                                     

       fullWidth
                                            value={this.state.employee.basic.email}
          

                              />
                                    </Grid>
                         

           <Grid item xs={12} sm={6}>
                                        <TextField onChange=

{this.onChange}
                                            required
                                          

  id="phone"
                                            name="phone"
                                         

   label="Teléfono"
                                            fullWidth
                                     

       value={this.state.employee.basic.phone}
                                        />
                  

                  </Grid>

                                    <Grid item xs={12}>
                 

                       <TextField onChange={this.onChange}
                                            

required
                                            id="address"
                                            

name="address"
                                            label="Dirección"
                                  

          fullWidth
                                            value={this.state.employee.basic.address}
     

                                   />
                                    </Grid>



                    

                <Grid item xs={12} sm={6}>
                                        <InputLabel 

htmlFor="birthdate">Fecha Nacimiento</InputLabel>
                                        
           

                             
                                        <TextField onChange={this.onChange}
  

                                          required
                                            id="birthdate"
 

                                           name="birthdate"
                                            

format="yyyy-mm-dd"
                                            type="date"
                                   

         fullWidth
                                            value={this.state.employee.basic.birthdate}
    

                                    />


                                    </Grid>
                   

                 <Grid item xs={12} sm={6}>
                                        <FormControl 

component="fieldset" >
                                            <FormLabel 

component="legend">Genero</FormLabel>
                                            <RadioGroup
     

                                           aria-label="gender"
                                               

 name="gender"

                                                value={this.state.employee.basic.gender}
       

                                         onChange={this.onChange}
                                            

>
                                                <FormControlLabel value="femenino" control={<Radio 

/>} label="Femenino" />
                                                <FormControlLabel 

value="masculino" control={<Radio />} label="Masculino" />

                                          

  </RadioGroup>
                                        </FormControl>
                            

        </Grid>



                                    <Grid item xs={12} sm={6}>
                    

                    <InputLabel htmlFor="title">Cargo a desempeñar</InputLabel>
                  

                      <Select name="title"
                                            fullWidth
           

                                 value={this.state.employee.job.title}
                                       

     onChange={this.onChangeJob}
                                            inputProps={{
                    

                            name: ´title´,
                                                id: ´title´,
       

                                     }}
                                        >
                          

                  <MenuItem value={´Programador´}> Programador </MenuItem>
                       

                     <MenuItem value={´Diseñador´}> Diseñador </MenuItem>
                        

                    <MenuItem value={´Community Manager´}> Community Manager </MenuItem>
         

                               </Select>
                                    </Grid>

              

                      <Grid item xs={12} sm={6}>
                                        <TextField 

onChange={this.onChangeJob}
                                            required
                              

              id="salary"
                                            name="salary"
                           

                 label="Salario pretendido"
                                            fullWidth
             

                               value={this.state.employee.job.salary}
                                        

/>
                                    </Grid>

                                    <Grid item xs=

{12}>
                                        <FormControlLabel
                                         

   control={<Checkbox required color="secondary" name="saveAddress" value="yes" />}
                    

                        label="Aceptar los términos y condiciones"
                                        

/>
                                    </Grid>
                                    <Button 

variant="contained" color="primary" type="submit" >
                                        

{this.state.titleButton}
                                    </Button>


                                

</Grid>

                            </form>
                        </Grid>
                  

      <Grid item xs={12} sm={6} style={{ backgroundColor: "#f5f5f5" }}>

                            

<Typography variant="h6" gutterBottom> Registros </Typography>

                            

<DataRecords  handleEdit={this.handleEdit} handleDelete={this.handleDelete} Nodata={this.state.nodata} 

Employees={this.state.employees} />

                        </Grid>

                    </Grid>

 

               </Container>

                <Dialog
                    open={this.state.open}
        

            onClose={this.handleClose}
                    aria-labelledby="alert-dialog-title"
               

     aria-describedby="alert-dialog-description"
                >
                    <DialogTitle 

id="alert-dialog-title">{"Se ha procesado satisfactoriamente."}</DialogTitle>

                    

<DialogActions>
                        <Button onClick={this.handleClose} color="primary">
       

                     Cerrar
                            </Button>
                    

</DialogActions>
                </Dialog>
            </React.Fragment>
        )
    }
}

export default Home;


Ahora vamos con el último archivo de nuestro ejemplo crud, el archivo DataRecords.js





import React, { Component } 

from ´react´
import Table from 

´@material-ui/core/Table´;
import TableBody from ´@material-

ui/core/TableBody´;
import TableCell from 

´@material-ui/core/TableCell´;
import TableHead from ´@material-

ui/core/TableHead´;
import TableRow from 

´@material-ui/core/TableRow´;
import Button from ´@material-

ui/core/Button´;
class DataRecords extends 

Component {
    render() {
        return (
            <Table 

>
                <TableHead>
         

           <TableRow>

                        

<TableCell align="left">Nombres</TableCell>

   

                     <TableCell 

align="left">Email</TableCell>
                        

<TableCell 

align="right">Acciones</TableCell>
                    </TableRow>
               

 

</TableHead>
                <TableBody>
                    {!this.props.Nodata ?
                

 

       this.props.Employees.map(row => {

                            const { employee } = row;

            

 

               return (
                                <TableRow key={employee.id}>
                   

 

                <TableCell component="th" scope="row">
                                        

{employee.basic.name}
                                    </TableCell>

                                  

  <TableCell align="left">{employee.basic.email}</TableCell>

                                    

<TableCell align="right">
                                        <Button size="small" 

variant="outlined" color="primary" onClick={() => this.props.handleEdit(employee.id)}>
                 

                           Ver/Editar
                                                            

</Button>
                                        <Button style={{ marginLeft: "10px" }} 

size="small" variant="outlined" color="secondary" onClick={() => this.props.handleDelete(employee.id)}

>
                                            Eliminar
                                                     

       </Button>
                                    </TableCell>
                                

</TableRow>
                            )
                        })

                        :
            

            ´No Data´
                    }

                </TableBody>

            </Table>
       

 )
    }
}

export default DataRecords;


Salimos de la carpeta components y abrimos el archivo App.css y lo editamos de esta manera:



.App {
  text-align: center;
}

.App-logo {
  

animation: App-logo-spin infinite 20s linear;
  height: 40vmin;
  pointer-events: none;
}

.App-header {
  

background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: 

center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: 

#61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate

(360deg);
  }
}


Procedemos a ejecutar en nuestro Terminal integrado de VisualStudioCode  el siguiente comando:

npm run build


Se habrá generado una carpeta llamada build dentro de nuestro proyecto. el contenido de la misma es el que subiremos a nuestro Hosting.


Podemos ver el ejemplo en vivo en el siguiente Link: https://reactfirebasetest.tupaginaonline.net/


acá una captura Final:


https://tupaginaonline.net/archivos/arc16_57_51.png






Si deseas tener tu página web, dale clic al botón de abajo

¡Ordena ya tu página web!


6105 vistas
Compartir:


Autor
Jose Fuentes

- Web Developer -

1 COMENTARIO(S)

Sebastian Hace 3 meses

Muy buena explicación. Yo tengo que consumir información de una API desarrollada en ASP.NET Core la cual expone los métodos GET, PUT, POST. Mi consulta es como poder consumir eso en React usando Hooks?

Contesta
Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *
Comentario *
Nombre *
Correo electrónico *
Sitio web

Articulos Relacionados
Articulos recientes

Desarrollos en venta

$ usd dólar 600