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!


1372 vistas
Compartir:


Autor
Jose Fuentes

- Web Developer -

0 COMENTARIO(S)
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 350