
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

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

Copiala en algún block de notas que lo vamos a utiliza mas tarde.
cd desktop
npx create-react-app my-app
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);
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
Podemos ver el ejemplo en vivo en el siguiente Link: https://reactfirebasetest.tupaginaonline.net/
acá una captura Final:

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