©2024 Escuela Tecnologías de la Información S.L. Todos los derechos reservados.
Curso de Progressive Web Apps con Polymer
Aprende a desarrollar aplicaciones progresivas (Progressive Web Apps, PWA) con Polymer 2
Material disponible
En este curso explicamos las técnicas y componentes disponibles para crear lo que se conoce como Progressive Web Apps, un nuevo modelo de aplicación web que ha revolucionado el desarrollo para la web.
Aprenderemos a crear aplicaciones usando la librería Polymer 2 y los componentes creados por el propio equipo de Polymer, por nosotros mismos y por terceros desarrolladores, lo que nos permitirá construir el proyecto montando bloques, a muy alto nivel. Esos bloques, los componentes, sirven para solucionar aspectos pequeños y específicos, pero montados en el marco de una aplicación son capaces de colaborar entre sí para resolver problemas globales.
Aprenderemos a crear aplicaciones usando la librería Polymer 2 y los componentes creados por el propio equipo de Polymer, por nosotros mismos y por terceros desarrolladores, lo que nos permitirá construir el proyecto montando bloques, a muy alto nivel. Esos bloques, los componentes, sirven para solucionar aspectos pequeños y específicos, pero montados en el marco de una aplicación son capaces de colaborar entre sí para resolver problemas globales.
Qué aprenderé en el Curso de Progressive Web Apps con Polymer
Objetivos del curso
El objetivo es aprender a manejar los componentes del catálogo de Polymer más útiles para construir Progressive Web Apps, desarrollando un proyecto completo donde podamos experimentar con elementos como el sistema de routing, los componentes de layout, los de acceso a datos, etc.
Por qué debes aprender Progressive Web Apps con Polymer
Gracias a los componentes de Polymer crear aplicaciones progresivas (PWA) es sencillo. Con ellas llegarás a realizar funcionalidades que nunca antes habían sido posibles para la web, como el cacheo de todo tipo de recursos, almacenamiento de datos, notificaciones, etc.
Qué tengo que saber
En este curso de desarrollo de aplicaciones progresivas partimos del conocimiento impartido en el Curso de Polymer 2. No hace falta ser experto en Polymer 2 para seguirlo, pero sí tener un conocimiento global sobre lo que la librería ofrece para el desarrollo de Web Components.
Clases y contenidos
Iniciar una aplicación con Polymer Starter Kit
- Conceptos generales sobre el desarrollo de aplicaciones progresivas con Polymer 2:
- Qué es Polymer
- Qué es Web Components
- Qué es Progressive Web Apps (PWA)
- Qué ventajas y posibilidades tienen las PWA
Cómo crear una aplicación con Polymer CLI, usando el template Polymer 2 Starter Kit, que nos ofrece una manera muy rápida de obtener una aplicación progresiva que podremos usar para empezar nuestro proyecto. Identificamos de manera muy general algunos detalles relativos a la estructura de proyecto.
En este vídeo se muestra cómo publicar la aplicación progresiva, para lo que usaremos el servicio gratuito de hosting de Firebase. Veremos cómo inicializar Firebase en nuestro proyecto y cómo enviar los archivos al servidor.
- Con este vídeo comenzamos nuestro checklist de características que deberían encontrarse en las aplicaciones progresivas. Veremos cómo auditar una página web, para conocer qué se puede mejorar e incrementar para que sea considerado una Progressive Web App.
- La extensión Lighthouse
- La necesidad de servir bajo HTTPS
- La necesidad de ser "responsive", con todo lo que ello implica (adaptabilidad a pantallas, conexiones, navegadores, etc.)
- En este fragmento observamos nuevos ítem en el checklist de las Porgressive Web Apps, con foco principalmente en el archivo manifest.json. Veremos elementos como:
- Instalación de la app en la lanzadera de iconos del dispositivo
- Cómo se produce la sugerencia de instalación en Android
- Qué son las "splash screen" y cómo generarlas
- Cómo debe ser el comportamiento de nuestra aplicación en cuanto a rutas (URLs) se refiere. Básicamente, cada página o pantalla de aplicación debe producirse mediante una ruta.
- Por qué es importante tener rutas para cada pantalla
- Cómo se generan las rutas en una aplicación SPA
- Un clic debe producir un comportamiento inmediato
- Service Worker
- Para qué sirve Service Worker y por qué es importante
- Cómo se genera un service worker en el proyecto con Polymer 2 Starter Kit
- Notificaciones Push y service workers.
En este último bloque de la primera clase de desarrollo de PWA con Polymer 2 mostramos, a modo de demostración, cómo se produce un componente y cómo se usa ese componente en el marco de la aplicación. Cómo se puede colocar el componente en una vista concreta para que pase a residir en el bundle concreto donde se necesita.
Desarrollo de aplicaciones progresivas con Polymer 2
- Flujo básico para trabajo con Git:
- Inicializar un repositorio, enviar código al repositorio local
- Subir un proyecto a un repositorio remoto de Github
- Clonar un repositorio remoto en local e instalar las dependencias
Mostramos un componente con el que podemos centrarnos en las partes fundamentales de la definición de custom elements en Polymer 2.
- Componente para visualizar una fecha en formato español. Detalles adicionales sobre Polymer y el flujo de trabajo para desarrollo, uso de los componentes y depuración:
- Propiedades de componentes
- Propiedades computadas
- Uso de this dentro de un componente
- Uso de this.$ para el acceso a los elementos dependientes de un componente, que tienen identificador definido
- Acceso a los componentes vía consola, para mostrar o manipular sus propiedades desde el propio navegador, lo que facilitará en el futuro muchas de las tareas de depuración
- Explicación básica de lo que es el API de un componente
- Este otro componente, que necesitaremos en nuestra aplicación a desarrollar durante el curso, sirve para generar una interfaz gráfica que nos permita trabajar como lo haría un interruptor, activando y desactivando algo. El componente reacciona a un clic y muestra su estado activo o desactivo. Como novedades en este componente encontraremos:
- Propiedades computadas que dependen de más de una propiedad del elemento
- Uso de métodos del ciclo de vida
- Declaración de manejadores de manera imperativa
- Trabajo básico con slots
- Cómo se usan los componentes que han creado terceras personas dentro del marco de nuestra aplicación.
- Cómo instalar componentes, cómo usarlos dentro de otros componentes nuestros y cómo personalizar su aspecto por medio de CSS y de estilos personalizados con variables CSS (custom styles).
En esta sección se abordan algunas preguntas que finalizarán la clase 2 del curso de desarrollo de aplicaciones Polymer 2, aplicaciones modernas o Progressive Web Apps.
Sistema de routing
- Componentes usados en el sistema de routing de Polymer: app-route y app-location.
- Comienzo de una aplicación para mostrar el sistema de routing, creado paso a paso con los componentes de routing, donde se irán incorporando funcionalidades durante esta clase.
En este vídeo se enseña a usar el componente iron-pages, que nos permite intercambiar contenidos con respecto a una propiedad del componente. Si esa propiedad está bindeada a los datos obtenidos del sistema de routing, conseguimos realizar una página que responde a las rutas de aplicación
Transformamos nuestro proyecto para que exista un componente por vista. Con el objetivo de descargar de código al componente principal y ordenar nuestra aplicación tendremos un componente para cada pantalla. Además esto nos permitirá más tarde facilitar la carga perezosa de componentes.
En este vídeo realizamos un cambio en los enlaces de la barra de navegación que nos permite mostrar el enlace que corresponde con la ruta activa. Para ello usaremos un nuevo componente del equipo de Polymer: iron-selector.
En este fragmento explicamos cómo es el proceso para la carga de componentes sólo cuando se accede a las rutas que lo necesita. Este proceso es conocido por carga perezosa o lazy load y en Polymer se realiza de una manera bastante sencilla.
Ahora vemos otra de las funcionalidades que se le debe pedir a todo sistema de routing, como es la gestión de parámetros en las rutas.
Conclusión y preguntas finales de la clase de Routing con los componentes de Polymer.
Layout
Explicaciones generales de los componentes de Layout ofrecidos por el equipo de Polymer. Realización básica desde cero de dos esquemas de layout, con barra lateral y cabecera y sólo con cabecera y sin barra lateral, en la que se ofrecen algunos trucos y consideraciones a llevar en cuenta a la hora de comenzar nuestro propia plantilla para la aplicación.
En este vídeo se muestra, ya sobre el proyecto de aplicación que estamos realizando para este curso, cómo personalizar los logotipos de la app y cómo agregar una paleta de colores elegidos a nuestro gusto. Se crearán diversas variables de CSS con colores que podremos ir usando durante la aplicación, para tener un esquema de colores consistente.
Sobre nuestra aplicación a desarrollar, realizamos algunas pequeñas modificaciones de color y textos en la cabecera y la incorporación de un logotipo de la app. Se verá cómo manipular los componentes app-header y app-toolbar para adaptarlos a nuestras necesidades.
En este vídeo se muestra cómo modificar y adaptar el estilo del componente app-drawer, que implementa nuestra barra de contenido lateral. Alteramos colores y alteramos también la personalización de la marca.
En este vídeo se muestra cómo crear nuestro propio set de iconos. En este set de iconos podremos colocar aquellos SVG que realmente vamos a usar en el desarrollo, evitando usar bibliotecas de iconos grandes, de los que solo necesitamos una parte. Luego se muestra cómo usar los iconos definidos en nuestro propio set de iconos, en varios sitios de la aplicación.
En este vídeo se muestra cómo alterar las rutas de la aplicación y los componentes del proyecto para que se usen en nuestras rutas cargadas por lazy load. Adaptamos las vistas genéricas ofrecidas en el starter kit y creamos una nueva ruta de aplicación para que se vea el proceso a realizar cada vez que se quiera agregar una nueva pantalla. Personalizamos el sistema de carga perezosa de componentes, para que los componentes puedan estar en otras rutas distintas de la raíz.
Acceso a datos por HTTP
- Comenzamos la clase del acceso por HTTP a recursos de un API REST enseñando cómo construir el API en pocos minutos. Para ello usaremos un paquete de npm llamado "json-server":
- Implementa un retardo en las conexiones Ajax, simulando que nos devuelve los datos un servidor remoto.
- Implementa una capa de login y autorización basada en JSON Web Token (JWT)
- Sistema para navegación "programatica" a otras rutas de aplicación.
- Formulario de alta de un marcador.
- Trabajo con el componente iron-ajax para realizar las conexiones HTTP con nuestro API REST.
- Explicamos iron-ajax
- Configuramos iron-ajax para la solicitud de inserción de un marcador
Cómo se podrían tratar las respuestas de las solicitudes Ajax, apoyados en eventos personalizados que implementa el componente iron-ajax. Estos eventos nos sirven para actuar ante respuestas positivas y negativas (de error) en las solicitudes realizadas.
En este vídeo se muestra una posible manera de presentar mensajes de feedback a los usuarios. Realizaremos una infraestructura sobre el componente raíz de la aplicación (my-app) que nos permitirá escuchar eventos personalizados. Cuando se detecten esos eventos se podrá mostrar los mensajes al usuario. Al final, este sistema permitirá que podamos disparar eventos desde cualquier componente de la aplicación, que serán tratados cuando lleguen, mediante la burbuja de eventos, al componente my-app. Además realizamos las modificaciones en el componente de inserción de un nuevo marcador, para que use el sistema de mensajes de feedback creado.
En esta ocasión hacemos un segundo ejemplo de conexión Ajax, para la home de la aplicación, en el que obtenemos el listado completo de marcadores. Ese listado se nos dará en forma de array, que podremos usar directamente sobre un template de repetición para mostrar el listado de marcadores insertado por el usuario.
En este vídeo se realiza una modificación para que los componentes que hacen solicitudes Ajax sean capaces de mostrar la típica ruedecita girando, indicando que se está esperando la respuesta del servidor. Lo realizaremos apoyados en otro componente llamado paper-spinner, bindeando el estado de "loading" que nos entrega el componente iron-ajax.
Componentes para el manejo de datos, estilo servicios
- Por qué queremos organizar el código de acceso a las API REST por medio de servicios, componentes no representacionales inspirados en los servicios de Angular.
- Cuál es el objetivo de los servicios y luego cómo vamos a hacer la arquitectura de la aplicación en base a esos servicios.
- Qué mecanismos vamos a usar para que los servicios estén disponibles en cualquiera de los componentes que los necesite.
En este vídeo veremos cómo implementar lo que sería la operación de lecturas, para obtener los datos del recurso y que el servicio los pueda entregar al resto de la aplicación.
Los datos del recurso, en este caso de los marcadores, se entregarán a otros componentes de la aplicación por medio de binding, lo que es bastante útil para conseguir que los otros componentes de la aplicación que usen ese listado sean capaces de mantenerse actualizados cada vez que cambia.
Además, también por binding, realizaremos una comunicación del estado de carga del servicio, de modo que otros componentes puedan mostrar la típica ruedita de "loading" cuando el componente del servicio está recuperando un nuevo array con el que actualizar el listado del recurso.
Aquí vamos a comenzar con lo que sería la operación para las inserciones desde el servicio. Esta operación requerirá de varios pasos, pero antes de hacer la inserción propiamente dicha nos vamos a centrar en otro asunto: el acceso a los servicios de manera global.
Veremos cómo desde el servicio y usando el componente iron-meta conseguimos guardar una referencia al componente del servicio.
Luego desde el componente de la inserción veremos cómo acceder al servicio, usando otro iron-meta que me permita recuperar esa referencia global al servicio.
Comprobaremos que el servicio está disponible desde el componente de inserción.
En este vídeo se realiza la operación de inserción, es decir, invocamos el método correspondiente al servicio que va a desatar la operativa para insertar. Veremos cómo en el servicio se implementa esa operación, por medio de otro iron-ajax. El servicio se encarga de toda la operación de inserción y comprobamos que los datos se almacenan en la base de datos. El servicio es capaz de saber el resultado de esa operación, gracias a los eventos del iron-a
El servicio necesita avisar a los componentes que lo usan sobre el resultado de las operaciones asíncronas que se le solicitan. Hasta este punto el servicio es capaz de saber si las inserciones, o cualquier otra operación, ha funcionado o ha dado un error. Pero ahora queremos mandar una señal a los componentes que usan el servicio para que éstos sean capaces de reaccionar cuando surgen respuestas de éxito o de error. Para ello usamos eventos personalizados dentro del servicio. Mostramos cómo disparar esos eventos personalizados y cómo podemos capturar esos eventos en los componentes donde se necesiten escuchar.
En los servicios necesitamos mostrar mensajes de feedback a los usuarios según se produzcan las operaciones, o surjan problemas causados por errores en las comunicaciones Ajax. Esos mensajes de error, o éxito, los coordinaremos de manera centralizada en el servicio, para descargar de trabajo a otros componentes. Además, cada vez que se produce una operación, se debe refrescar el listado de servicios que se ha recuperado y se está bindeando a otros componentes de aplicación. De este modo, el listado de marcadores de la home se actualizará automáticamente cuando se haya enviado un nuevo marcador a la base de datos.
En este vídeo se muestra cómo se realiza una nueva operación en nuestro servicio. Esa operación permitirá borrar un marcador. Se crea un nuevo componente para el listado de marcadores, con un botón para borrar. Al pulsar ese botón, usando el servicio, se invoca la operación de borrado pasando el id del marcador a borrar. En el servicio se realiza la operativa para borrado, usando un nuevo iron-ajax.
Queremos conseguir que, al pulsar un botón para borrar un elemento, que ese elemento cambie su estado para mostrar que se encuentra en proceso de borrado. Luego, una vez la operación haya terminado, el componente desaparecerá normalmente del listado. Sin embargo, mostramos un problema que surge por el componente "template dom-repeat", que al reutilizar elementos del DOM, no desmarca el estado de borrado de los elementos. Explicamos bien este problema y mostrarmos una posible vía para su solución.
Autorización por web token
- Autenticación y autorización del usuario en nuestra aplicación, con backend basado en API REST.
- Cómo funcionan las API REST estándar, en las que tenemos que hacer un proceso de login un poco especial, debido a que REST no mantiene el estado de la aplicación, es decir, no se usa una sesión del lado del servidor y por tanto no recuerda al usuario entre llamada y llamada. - Registro de usuario
- Login de usuarios
- Autorización de rutas REST protegidas
- Verificación de un usuario autenticado anteriormente (cómo recordar al usuario aunque se refresque la página o se cierre el navegador)
En este bloque simplemente se muestran unas modificaciones realizadas en la aplicación, previas al inicio de la clase.
Básicamente se trata de mostrar las rutas que hemos creado en la aplicación, para los formularios de registro y de login, los cuales comparten un mismo formulario, que hemos definido en un componente que usarán tanto la ruta de registro como la ruta de login.
En este vídeo se muestra cómo se implementa la parte del registro de usuarios. Para ello nos llevaremos la lógica de registro al componente user-service, que será el que tenga que realizar las llamadas HTTP contra el servidor para crear nuevos usuarios. Una vez registrado un usuario se hace una redirección a la página de login, para lo que se crea un nuevo mixin, que contiene la función que podremos usar en cualquier componente que necesite, de manera programática, navegar a una nueva dirección (URL) de la aplicación.
En este vídeo se realiza la implementación del flujo de aplicación correspondiente al proceso de login. Se parece bastante a la lógica del proceso de registro, con la diferencia que en el proceso de login se recibe el token, que tendremos que almacenar para que en las posteriores solicitues al API seamos capaces de informar al servidor sobre el usuario que está realizando esa solicitud.
En esta ocasión vamos a implementar la operativa para hacer el logout del usuario. Para ello hacemos una modificación, para que el botón de login se sustituya por el botón de logout, en el momento que el usuario está autenticado. Luego realizamos el comportamiento del botón de logout.
En este vídeo vamos a realizar el proceso de autorización, necesario para las rutas protegidas. Nuestro sistema de API REST tiene como rutas públicas todas las rutas "GET". Sin embargo, todas las rutas que son de otro método (HTTP method) como "DELETE", "POST", "PUT", etc. necesitan ser realizadas por un usuario autenticado. Es decir, salvo la recuperación de datos, todo lo que sea escrituras, necesitan autorizar al usuario. La autorización se realiza por medio del token, el cual se debe enviar en la solicitud dentro de las cabeceras (HTTP Headers).
En este vídeo se realiza un comportamiento también muy necesario con nuestra aplicación. Se trata de almacenar el token en el localstorage. Esto es necesario porque, cada vez que la página se refresca, se pierde el token. Es cierto que al ser una SPA el usuario no debería refrescar la página, pero si lo hace no queremos que se pierda el token que se recibió al loguearse. También, si se va dejando la sesión abierta, navega por otras webs y vuelve al cabo de un rato a la aplicación, queremos que se recuerde al usuario. Incluso, si el usuario cierra el navegador y vuelve a abrirlo entrando a la aplicación, queremos que se recuerde al usuario. Para todo ello, se implementa un almacenamiento en el sistema del local storage del navegador, del token de autenticación recibido al hacer el proceso de login. Pero claro, aunque almacenemos el token, realmente nuestra página no tiene por qué enterarse, de modo que hay que hacer una comprobación para que, si se detecta un token almacenado, se verifique que corresponde con un usuario con sesión abierta, y se verifique que el token no ha caducado. Por ello hay que hacer una operativa de verificación del token contra el servidor del API REST y, una vez verificado, cambiar el estado de la aplicación para marcar que el usuario está logueado.
- Solucionamos el problema del item que, al intentar borrarse con fallo, no se actualizaba su estilo para quitarle la clase que lo marca como "en proceso de borrado".
- Atendiendo a una pregunta, realizamos un proceso para ocultar ciertas opciones en el navegador, de modo que no las vean los usuarios que no están logueados. Además hacemos una comprobación en las páginas que deberían estar protegidas, para que usuarios no logueados no sean capaces de verlas.
Sesión Extra: edición de marcadores
Comemzamos la clase explicando un componente que hemos incorporado al proyecto de manera previa. Es un componente de interfaz de usuario que nos permite visualizar más opciones, por medio de un icono y un overlay que se muestra al pulsar dicho icono. Explicamos cómo altera eso nuestro componente marcador-item y los motivos por los que hemos decidido incorporar este nuevo componente.
Ahora explicamos cómo se ha construido una nueva ruta en la aplicación, en la que estamos pasando parámetros. Esto es algo que depende del sistema de routing de los componentes, visto en una clase anterior, que ahora incorporamos como un ejemplo real en nuestra aplicación. Explicamos cómo generar esa nueva vista y cómo permitir que esa vista esté atenta a partes de la ruta de direcciones, a partir de la que debebe obtener el parámetro que necesita (el id de un marcador que se pretende editar).
- En este vídeo resolvemos algunas dudas realizadas a raíz del vídeo anterior, relacionadas con el sistema de routing de Polymer.
- Por qué colocamos componentes que implementan rutas en carpetas, a pesar que nos obliga a modificar el código de my-app.
- Por qué en el componente que lee parámetros de la ruta estamos obligados a usar otro componente app-route.
Este componente tiene un asunto específico que dificulta la operativa con el servicio de marcadores y su coordinación con la recepción del parámetro de la ruta. Básicamente ocurre que conocemos antes el identificador del marcador a editar que el servicio de marcadores. Por tanto, debemos asegurarnos que el servicio esté disponible antes de procesar la ruta para acceder al objeto del marcador determinado.
En este vídeo explicamos cómo funciona el marcadores-service para obtener el dato de un marcador que se pretende editar. Cómo el marcadores-service pasa el dato al componente marcadores-editar. Y finalmente, cómo marcadores-editar mostrará ese dato dentro de un formulario.
Por fin, con los datos del marcador editados en el formulario, realizamos la operativa de enviarlos a la base de datos usando el marcadores-service. Además se resuelven dudas del final de la clase.
Firebase y Polymer
Qué es Firebase, qué tipos de servicios ofrece. Concepto de Backend-as-a-Service. Qué podemos usar de manera gratuita de Firebase y cuándo se comienza a tarificar por el servicio.
- Cómo instalar los componentes para usar Firebase desde Polymer, dentro del paquete "Polymerfire" y cómo integrar el componente firebase-app para indicar nuestras claves de acceso a las API de Firebase.
- Instalamos los componentes Polymer.
- Realizamos los import
- Usamos el firebase-app
- Obtenemos las claves de API desde la consola de Firebase
- Personalizamos el componente firebase-app con nuestras claves.
- En este vídeo mostramos cómo realizar las primeras escrituras en la base de datos en tiempo real que nos ofrece Firebase.
- Explicamos cómo acceder al API de acceso a base de datos desde nuestros componentes.
- Distribuimos el acceso a Firebase a otros componentes de la aplicación.
- Realizamos una escritura sobre una referencia de la base de datos.
- Introducimos las reglas de seguridad de la base de datos.
En esta ocasión realizamos una escritura en una colección, que técnicamente permite tener varios elementos en una referencia, donde cada uno de ellos tiene lo que se llama un "push id".
Para ello simplemente usamos la el método push(), que se encarga de generar el push id incremental y luego escribir el marcador dentro de esa referencia.
En este bloque mostramos cómo se puede crear un servicio, un componente no representacional que nos sirve para gestionar un recurso. La novedad, con respecto a otros componentes como servicios que habíamos realizado ya en la aplicación, es que ahora el acceso a los datos se realiza mediante Firebase.
Además conocemos el componente firebase-query que sirve para acceder a una colección y recuperar todos sus elementos en forma de array.
Nuestro servicio recuperará el listado de marcadores y lo expondrá mediante doble binding para cualquier otro punto de la aplicación donde lo necesitemos.
Ahora que tenemos el servicio lo podemos usar. Para ello guardamos el servicio en un iron-meta, igual que hemos hecho con otros servicios anteriormente, de modo que podremos acceder al componente desde cualquier lugar donde se necesite. Luego modificamos la aplicación para apoyarnos en este servicio y realizar las operativas de trabajo con los datos de Firebase. Resolvemos dudas diversas, como la de colocar las claves del API visibles para todo el mundo o el trabajo offline usando componentes de Polymer.
A modo de demostración, se explica el componente firebase-auth, que sirve para autenticar usuarios usando el servicio de autenticación de Firebase. En este vídeo se presentó un problema por tener un service worker instalado en el hosting de Firebase asociado a esta aplicación. Este problema se resolvió eliminando una aplicación que estaba en el espacio de hosting, pero se explicarán detalladamente los motivos del error más adelante en la clase de deploy de la PWA.
En este vídeo agregamos una nueva operación al servicio, para el borrado de un elemento. Luego implementamos el botón de eliminar un marcador, apoyándonos en el servicio.
Se dan algunos detalles sobre cómo usar Firebase en diversos modos y cómo agregar funcionalidad necesaria en aplicaciones, como la de pagos electrónicos.
Notificaciones Push
En esta introducción repasamos los integrantes del servicio de notificaciones y el flujo a aplicar para implementar las notificaciones push para la web. Repasamos los conceptos que debemos conocer para desarrollar la parte de las notificaciones.
- En esta primera fase práctica vamos a realizar una serie de modificaciones en el proyecto, que nos sirvan de base para disponer de la infraestructura necesaria para implementar las notificaciones.
- Indicar el sender id global en el manifest.json
- Crear el service worker necesario para recibir notificaciones
- Incluir nuestro sender id en el componente firebase-app
- Incluir el componente firebase-messaging
- En este vídeo vemos uno de los momentos más importantes del flujo de notificaciones, en el que se solicita permiso al usuario para enviarle las notificaciones.
- El usuario puede aceptar recibir notificaciones, o puede bloquearlas.
- En el caso que las acepte obtenemos el famoso token :)
En este bloque se explica un componente de Polymerfire para el acceso a documentos de la base de datos de Firebase.
Modificaciones necesarias en user-service, enfocadas en que este servicio pueda informar del email del usuario autenticado.
Operativa del almacenamiento del token de las notificaciones push.
En este vídeo realizamos la prueba de todo el código anterior, ya que se demuestra que se reciben las notificaciones.
Cómo se reciben notificaciones cuando el sitio está abierto en una pestaña activa. En este caso no se recibe la notificación propiamente dicha, sino que se tiene que implementar un manejador de evento para manejarla en el propio sitio.
Firebase Cloud Function
Aunque no tenga que ver realmente con el contenido del curso, vamos a ver en los siguientes vídeos cómo se envían las notificaciones, apoyados por algo de programación del lado del servidor, necesaria para este proceso. Comenzamos explicando qué son las Firebase Cloud Functions, el backend que hemos escogido para el envío de las notificaciones, que nos permite ejecutar código del lado del servidor, aunque sin disponer de un servidor propiamente dicho. Ofrecemos algo de información teórica y mostramos ya por la práctica cómo se puede empezar a trabajar con cloud functions en un proyecto.
A continuación explicamos la cloud function que usamos para el envío de la notificación a los usuarios que hayan solicitado que las desean recibir. El código es NodeJS, que se ejecutará del lado del servidor, usando las API de Firebase.
Cómo se realiza el deploy de una Firebase Cloud Function, usando Firebase CLI. Por medio de un sencillo comando de consola se sube el código a Firebase. Una vez realizado el proceso, se prueba nuestra función cloud.
Esto no depende directamente de Cloud Funcions, pero el proceso de envío de notificaciones desencadena una escritura de la fecha en la que se compartió un marcador. En el lado del cliente queremos mostrar esa fecha de manera sencilla de leer para humanos. Para trabajo con fechas es muy cómodo usar la librería MomentJS, que tenemos que instalar en nuestro proyecto frontend. Mostramos cómo instalar scripts del lado del cliente, que cargaremos por medio de HTML Imports, como si fueran otros componentes de aplicación.
Proceso de Build
Comenzamos las explicaciones del proceso de build de aplicaciones Polymer. En este vídeo presentamos el archivo polymer.json que nos sirve para especificar cómo se va a realizar el proceso de build. Luego se distingue entre los archivos que se irán a la shell y los archivos que se irán a los bundles de cada fragmento cargado mediante Lazy Load.
- En este vídeo vemos otros detalles sobre la configuración del proceso de build mediante el archivo polymer.json:
- sources (todos los archivos fuente del código que se deben copiar a la carpeta de producción)
- extraDependencies (Dependencias extra de código que el analizador de Polymer no puede deducir, posiblemente porque se carguen de manera dinámica)
- builds (Todos los presets, o tipos de generación de código que debe realizar)
Durante el proceso de build podríamos encontrar errores que no se han visto durante la etapa de desarrollo. Esos errores nos aparecerán en la consola. En este vídeo no tenemos errores, pero tenemos un par de warnings debidos a los mixin, que el analizador de Polymer no es capaz de entender bien, al no conocer la clase sobre la que se van a aplicar los mixins.
Una vez se han generado los archivos para poner a producción la aplicación, los vamos a subir a un hosting remoto donde estarán disponibles para el acceso por parte del público. Usaremos el hosting que nos ofrece Firebase de manera gratuita.
Configuración PWA vía manifest.json
Conocemos más a fondo el archivo manifest.json, una de las utilidades más importantes para la realización de las PWA. Este archivo permite, de una manera muy cómoda y prácticamente sin necesidad de conocimientos técnicos, configurar la aplicación para conseguir cosas novedosas, no disponibles hasta ahora en aplicaciones web. Configuramos los aspectos básicos del manifest de nuestra aplicación.
Cómo el manifest.json permite configurar el banner automático que produce el navegador, sugiriendo al usuario la instalación de la aplicación entre los botones del dispositivo. En qué condiciones se consigue que aparezca el banner para la instalación de la aplicación. Una vez instalada, cómo se puede configurar la llamada "splash screen", también a través del manifest.json.
Funcionamiento offline de la aplicación
Cómo realizar un componente que detecte el estado del usuario, conectado o desconectado, mostrando con un icono. Este vídeo es interesante también porque implementamos un behavior de Polymer 1.x en un componente realizado con Polymer 2.x Adicionalmente se muestra cómo bloquear cierta funcionalidad, como el login en la app, para que funcione solamente con el usuario logueado.
En este vídeo realizamos la configuración del Service Worker, que se va a generar en el proceso de Build. Polymer Starter Kit en este momento usa la librería "SW-Precache" y nos permite, mediante un json que se escribe en el archivo "sw-precache-config.json", decirle cómo debe cachear las cosas.
La librería "SW-Precache" también permite cachear archivos que se puedan llegar a requerir en tiempo de ejecución. Para ello usamos otra configuración del archivo "sw-precache-config.json"
En la práctica, no todo se puede cachear con el service worker generado por "SW-Precache". Realmente hay datos que no te vienen por endpoints HTTP y por tanto no puedes cachear normalmente. Por ejemplo esto ocurre con los datos que te vienen desde Firebase. Este trabajo se podría hacer de diversas maneras, pero explicamos una que usa un componente ofrecido por Polymer para hacer un mirror de datos en IndexedDB.
En este vídeo resolvemos un problema común que te encontrarás si haces uso del sistema de login de Firebase. Básicamente hay rutas del hosting que no se deberían cachear con el service worker y por ello tenemos que desactivar el cacheo de ciertas rutas reservadas a Firebase.
En este vídeo mostramos una manera más optimizada de registrar el service worker. Además se muestra un código de registro más elaborado, que nos permite saber cuándo un service worker se ha actualizado, para saber las ocasiones en las que decirle al usuario que debe actualizar la página, para recibir los cambios de la app.
Una vez que se ha detectado que se intenta registrar un archivo de Service Worker actualizado, podemos indicar al usuario que realice la recarga de toda la app. En este vídeo se complementan las explicaciones del punto anterior, mostrando cómo actuar para recargar la página y demostrando que nuestras modificaciones funcionan correctamente.
Redux
En este primer vídeo explicamos lo que es Redux, como patrón de diseño de software, sus objetivos, ventajas y modos de trabajo, diagrama de funcionamiento, etc. Se introducen los conceptos de store, acciones, reducers.
En esta clase vemos la implementación de Redux en Polymer, los primeros pasos, por medio de un mixin que se usará en todos los componentes que necesiten trabajar con el store, para modificar el estado de la aplicación o recuperarlo como valor en una propiedad. Se implementa el estado inicial, la store y se construye el ReduxMixin.
En este vídeo conocemos el mecanismo para bindear los datos existentes en el store y poder acceder a ellos desde los componentes de Polymer. Aprendemos lo que se llama el binding estático, a través de la declaración "statePath" de las propiedades del componente, que básicamente nos suscribe a un dato del store que podamos necesitar en el componente.
Veremos el envío de nuestra primera acción y su implementación. En este vídeo se muestra cómo alterar los datos que están en el store, por medio del dispatch de acciones (el disparo de acciones). Esas acciones se lanzan desde los componentes y llegan al reducer, que las tiene que implementar. En el vídeo también se explica cómo es la implementación de acciones en el reducer.
En este bloque vemos un nuevo ejemplo de acción en la que se envían datos adicionales al reducer, necesarios para procesar la acción disparada. Se verá también una segunda implementación de acción en el reducer.
En este vídeo comenzamos un segundo ejemplo de Redux con Polymer, en el que veremos cómo hacer un tratamiento de arrays en el store. En este ejercicio comenzamos un todo-list (una lista de tareas) rudimentario. Para comenzar hacemos la parte de crear nuevas tareas. Para definir el action de crear una tarea aprendemos un mecanismo de Redux que se llama "action creator", que nos sirve para separar la lógica de creación de la acción, de modo que la podríamos tener en un mixin que seríamos capaces de usar desde varios componentes, con una única implementación.
En este bloque explicamos un segundo mecanismo de bindeo de datos que tenemos en el store a propiedades de los componentes. Se conoce como dinamic bindings y también aporta algo más de flexibilidad al bindeo de datos, ya que nos permite acceder al dato y quedarnos con la parte que nos interesa, o incluso transformarla antes de asignarla a la propiedad del componente. Es idóneo para el trabajo con arrays y con objetos complejos.
Este bloque es importante porque aborda una de las limitaciones de polymer-redux en el trabajo con objetos y arrays, ya que al suscribirnos a datos complejos (subpropiedades y arrays) no seremos capaces de percibir cambios en las propiedades profundas de los objetos o de la mutación de arrays. Para demostrarlo, en este vídeo realizamos unas pruebas un poco más detalladas con un array que nos viene desde el store. Aprendemos cosas que nos pueden ocurrir en el uso del array en el template, concretamente al recorrerlo con un template de repetición. Veremos cómo solucionar estos problemas con mecanismos más precisos de detección de cambios en la librería Polymer, con mutable data, tanto en el template como en los propios componentes.
Este vídeo es una introducción a las situaciones relacionadas con las acciones asíncronas en Redux. Se explica de manera resumida cuál es el problema que tenemos al tratar con acciones asíncronas, que requieren generalmente de la ejecución de la acción pasados unos segundos, que dependen del tiempo de respuesta de esa operación asíncrona. Para enseñar a Redux a tratar las acciones asíncronas se usa un paquete de npm llamado redux-thunk, que se deberá instalar en el proyecto.
- Implementación de una acción asíncrona usando Redux y Redux-thunk. Se verá cómo realizar una acción compuesta por dos partes, una que se ejecuta instantáneamente y otra que se deriva para su ejecución más tarde, cuando se completa la acción asíncrona.
En este vídeo veremos algunas referencias sobre contenidos que tienen que ver con Redux en Polymer 2, junto con conclusiones y otras preguntas formuladas al final de la clase.
INTRODUCCIÓN A POLYMER 3
Desarrollos en Polymer 2 que desean actualizarse a Polymer 3
Actualización a Polymer 3 y diferencias entre las versiones de la librería y flujo de desarrollo esencial con Polymer CLI.
Valoraciones
Mª Angeles
Joel Coll
¿Conoces nuestra tarifa plana?
Toda la formación de EscuelaIT, con más de 200 cursos completos para aprender las más variadas tecnologías de programación, diseño y marketing online. Todo! con tu suscripción.