En esta página:
Demo
Vamos a continuar con con la parte anterior llamada Como Crear un CRUD con Firebase 7.14.2 y Bootstrap 4 – Parte 4, en donde trabajamos la operación Read (Leer) del sistema CRUD, diseñamos la vista HTML con elementos de Bootstrap 4 y creamos el código JavaScript que realiza la llamada de los datos desde Firebase Realtime Database, para ser leídos en la vista, en esta Parte 5 vamos a trabajar en la operación Update (Actualizar) de nuestro sistema CRUD, vamos con ello.
Partes
Antes de continuar, te invito a leer los siguientes artículos para que estés familiarizado con este tutorial:
Asimismo te invito a escuchar el Podcast: “5 Consejos para ser un Programador más Productivo” (No son los clásicos consejos técnicos de programación, si no de rutinas y buenos hábitos cotidianos):
Spotify: | Sound Cloud: |
Bien ahora continuemos con el Post: Como Crear un CRUD con Firebase 7.14.2 y Bootstrap 4 – Parte 5
Update (Actualizar)
Vamos a crear la tarea Update (Actualizar), mediante un formulario el usuario podrá editar los datos de un determinado registro, para que el sistema sepa que registro debe actualizar, voy a pasarle el id o key del registro que quiero eliminar.
El id o key que usaré es el mismo que Firebase Realtime Database me generó al insertar un dato, en la Parte 6 de este tutorial voy a crear una vista principal, desde donde envio el id o key a la vista actualizar para indicarle el id o key que debo actualizar.
Comencemos con la Vista de la tarea actualizar, en ella colocaré un formulario y dentro de cada campo colocaré los valores del registro que se va actualizar, para esto voy a llamar a la función JavaScript cargarDatos(), esta función la crearemos más abajo y se encargará de colocar al cargar la página cada valor de un registro en el campo correspondiente del formulario.
1 2 3 4 5 |
<body onload="cargarDatos();"> <!-- Acá va mi código HTML -- > </body> |
Ahora antes del formulario para actualizar los datos, coloco un botón para volver a la vista principal, si es que el usuario no desea editar el registro.
Luego colocaré el formulario, en el evento onsubmit(), es decir al enviar el formulario con los cambios, llamo a la función JavaScript actualizar() la cual se encarga de actualizar los campos y la imagen en Firebase Realtime Database y Firebase Storage para la imagen.
A diferencia de la vista Read (Leer), en nuestra vista Actualizar voy a mostrar la imagen actual que se encuentra adjunta al registro que estoy actualizando.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<!-- Botón para volver a la vista principal --> <a type="button" href="index.php" class="btn btn-success mb-2">Volver</a> <form id="actualizar" onsubmit="actualizar(); return false;"> <div class="form-group"> <label for="nombre" class="negrita">Nombre</label> <input type="text" class="form-control" id="nombre" placeholder="Torta de Chocolate" required> </div> <div class="form-group"> <label for="precio" class="negrita">Precio</label> <input type="text" class="form-control" id="precio" placeholder="3.00" required> </div> <div class="form-group"> <label for="stock" class="negrita">Stock</label> <input type="text" class="form-control" id="stock" placeholder="46" required> </div> <div class="form-group"> <p class="img"> <strong>Imagen Actual:</strong> <br> <img class="img-fluid mt-2" id="img" width="50%"> </p> <label for="img" class="negrita">Imagen</label> <div class="custom-file"> <input type="file" class="custom-file-input" id="img" accept=".jpg, .jpeg, .png, .svg, .webm" onchange="leerImagen(event);"> <label class="custom-file-label" for="customFile">Selecciona una Imagen</label> </div> </div> <button type="submit" class="btn btn-primary">Aceptar</button> </form> |
Si voy al navegador, debería ver la vista Actualizar, de la siguiente manera. (Puedes apreciar en la barra de navegación, he pasado el id o key del registro que quiero actualizar en Firebase Realtime Database).
Bueno ahora pasemos a crear el código JavaScript para nuestra tarea Update (Actualizar).
Debajo antes de la etiqueta de cierre </body> colocaré el código JavaScript que realiza la operación CRUD Update (Actualizar).
Primero defino la configuración de Firebase , luego inicio Firebase con la configuración definida o realizada y hago referencia a Firebase Realtime Database.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Configuración de Firebase var firebaseConfig = { apiKey: "Tu apiKey", authDomain: "Tu authDomain", databaseURL: "Tu databaseURL", projectId: "Tu projectId", storageBucket: "Tu storageBucket", messagingSenderId: "Tu messagingSenderId", appId: "Tu appId", measurementId: "Tu measurementId", }; // Inicializo Firebase firebase.initializeApp(firebaseConfig); firebase.analytics(); // Hacemos referencia a Firebase Realtime Database var database = firebase.database(); |
Luego creo una variable llamada key que usaré para cada dato del registro, también creo una variable llamada datosurl en donde obtengo el id que he pasado por la URL desde la vista principal a la vista Read (Leer).
1 2 3 4 5 6 |
var key; // Obtengo el id de la URL var datosurl = new URLSearchParams(window.location.search); |
Bien, ahora crearé la función cargarDatos() la cual llama a los datos de un registro y los coloca dentro de cada campo correspondiente en el formulario de la vista Update (Actualizar), he colocado comentarios para explicar que hace cada parte del código.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
function cargarDatos() { // Selecciono los datos desde postres var database = firebase.database().ref().child('postres'); database.once("value") .then(function(snapshot) { snapshot.forEach(function(data) { // Verifico si los 'ids' coinciden const id = datosurl.get('id'); const key = data.key; // Verifico si los 'ids' o 'keys' coinciden y muestro solos los datos de ese 'id' o key if (id == key) { var iedit = id; var nombre = data.val().nombre; var precio = data.val().precio; var stock = data.val().stock; var img = data.val().img; // Variable Global de la URL de la imagen actual, la uso en la función actualizar() window.imgfs = img; // Envío los datos a la vista HTML $('#nombre').val(nombre); $('#precio').val(precio); $('#stock').val(stock); $('#img').attr('src', img); } }); }) } |
Algo importante que me parece debes aprender del código anterior, es que para obtener los datos de un solo registro por su id, lo que hago es verificar si la id de la URL es igual al id del registro almacenado en Firebase Realtime Database.
1 2 3 4 5 6 7 8 9 10 |
// Verifico si los 'ids' coinciden const id = datosurl.get('id'); const key = data.key; // Verifico si los 'ids' o 'keys' coinciden y muestro solos los datos de ese 'id' o key if (id == key) { // Mostramos solo los datos de ese registro en el formulario } |
Ahora voy a crear la función leerImagen(), esta función la puse en el campo img del formulario, cada vez que selecciono una imagen, este campo llama a la función leerImagen() y obtiene la imagen como un objeto File mediante la API File de HTML 5.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Obtengo la imagen como objeto File haciendo uso de la API File de HTML5 function leerImagen(event) { var fileList = event.target.files[0]; // Cambio el nombre de la imagen var blob = fileList.slice(0, fileList.size, fileList.type); var nuevoArchivo = new File([blob], Date.now() + '.' + fileList.name.split('.').pop(), { type: fileList.type }); // Obtengo el objeto y lo coloco en una variable global para usarla en mi función crear() window.value = nuevoArchivo; window.nombreimg = nuevoArchivo.name; console.log(nuevoArchivo); } |
Cuando el formulario es enviado, este llama a la función actualizar() la cual crearé a continuación, en ella obtengo la url en donde esta el id del registro actual que quiero actualizar, luego hago referencia o le indico al sistema que los datos que actualizaré son los que se encuentra en postres.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function actualizar() { try { // Obtengo el id de la URL var datosurl = new URLSearchParams(window.location.search); // Selecciono los datos desde postres var database = firebase.database().ref().child('postres'); database.once("value") } } |
Ahora usaré una Promise (Promesa) en donde hago uso del método forEach() de JavaScript para recorrer cada valor del registro y verifico si el id o key de la URL es igual al del registro, luego obtengo los valores del formulario, hago una referencia a Firebase Storage en donde guardare el archivo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
.then(function(snapshot) { snapshot.forEach(function(data) { // Verifico si los 'ids' coinciden const id = datosurl.get('id'); const key = data.key; // Verifico si los 'ids' o 'keys' coinciden y muestro solos los datos de ese 'id' o key if (id == key) { // Obtengo los datos del formulario var nombre = $('#nombre').val(); var precio = $('#precio').val(); var stock = $('#stock').val(); var img = window.nombreimg; // Subida de la imagen a Firebase Storage // Creo una referencia al root de Firebase Storage var storageRef = firebase.storage().ref(); // Creo una referencia para un archivo var archivoRef = storageRef.child('crud_firebase_bootstrap/uploads/' + img); } }) }); |
Ahora voy hacer uso de sentencias if – else para verificar si el objeto del archivo (imagen) esta vacío, ya que el usuario por ejemplo puede elegir solo editar el nombre y no la imagen, así no enviamos un archivo vacío a Firebase Storage y Firebase Realtime Database.
Si el objeto del archivo (imagen), no esta vacío, obtengo la imagen actual alojada en Firebase Storage, pero Firebase Storage me pide que envíe el nombre de la imagen solamente, para esto voy a extraer el nombre de la imagen que esta en la URL de esta.
Hago referencia a Firebase Storage y a la ruta en donde se encuentra alojada la imagen que quiero eliminar y procedo a eliminar la imagen.
Luego hago uso de una Promise (Promesa) de JavaScript para subir la nueva imagen, obtengo la url de la nueva imagen, hago referencia a Firebase Database Realtime, inserto los nuevos datos y redireccionamos a la vista principal con un mensaje.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
if (window.value != null) { // Obtengo la imagen actual (Hago extracción del nombre de la imagen en la URL) var str = window.imgfs; var n = str.split('%2F').pop().split('#').shift().split('?').shift(); //var n = str.split('/').pop().split('?')[0]; // Hago referencia a Firebase Storage var storage_eli = firebase.storage(); var storageRef_eli = storage_eli.ref(); // Hago referencia a la ruta del archivo almacenado en Firebase Storage var desertRef = storageRef_eli.child('crud_firebase_bootstrap/uploads/' + n); // Elimino la imagen desertRef.delete().then(function() { console.log('Imagen Eliminada de Firebase Storage !'); }).catch(function(error) { console.log(error); }); // Subo la nueva imagen a Firebase Storage con el método put() // Le paso la variable global 'windows.value' que contiene el objeto File de la imagen archivoRef.put(window.value).then(function(snapshot) { console.log('Imagen Subida a Firebase Storage !'); }).then(function() { // Obtengo la URL de la imagen archivoRef.getDownloadURL().then(function(downloadURL) { console.log('URL de la imagen: ', downloadURL); window.urlimagen = downloadURL; // Hacemos referencia a Firebase Realtime Database var database = firebase.database(); // Defino la ruta '/postres' con el 'id' del registro en la base de datos Realtime Database const ref = database.ref('postres/' + id); // Actualizo los datos en en la base de datos Realtime Database ref.update({ nombre: nombre, precio: precio, stock: stock, img: window.urlimagen }); // Redireccionamos con mensaje var msg = "Actualizado Satisfactoriamente !"; window.location = 'index.php?mensaje=' + msg; }); }); } else { // Código para la sentencia 'else' } |
Y si el usuario decide no cambiar la imagen, en la sentencia else actualizamos los datos sin la imagen, redireccionamos a la vista principal con un mensaje y termino con el catch() que me muestra algún error si es que es encontrado.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
else { console.log("No se ha seleccionado una imagen"); // Hacemos referencia a Firebase Realtime Database var database = firebase.database(); // Defino la ruta '/postres' con el 'id' en la base de datos Realtime Database const ref = database.ref('postres/' + id); // Actualizo los datos en en la base de datos Realtime Database ref.update({ nombre: nombre, precio: precio, stock: stock, img: imgfs }); // Redireccionamos con mensaje var msg = "Actualizado Satisfactoriamente !"; window.location = 'index.php?mensaje=' + msg; } catch (err) { console.log(err); } |
Puedes ver que estoy haciendo uso del método update() de Firebase Realtime Database, el cual nos permite actualizar los registros en la base de datos.
Yo estoy usando try…catch de JavaScript para encontrar los errores en mi código, tu puedes elegir no usarlo, no hay problema.
Bien, eso es todo para la Parte 4 de este tutorial, hemos creado la vista HTML Update (Actualizar) con Bootstrap 4 y también creamos el código JavaScript para actualizar la imagen y los datos de un solo registro por su id.
Ten Paciencia, lo que quiero es que entiendas todo el proceso para Crear este Proyecto y no llenarte el capitulo de mucho contenido porque te puedes marear y no tendrás un óptimo aprendizaje.
Nota (s)
- En la siguiente Parte de este tutorial crearemos la última operación o tarea del sistema CRUD, es decir la tarea Delete (Eliminar).
- No olvides que debemos usar la Tecnología para hacer cosas Buenas por el Mundo.
Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos.