Creación de aplicaciones móviles multiplataforma en tiempo real: ejemplos con Ionic Framework y Firebase

Publicado: 2022-03-11

Uno de los principales problemas que enfrentan las empresas al crear una aplicación para teléfonos inteligentes es el costo multiplicador de crear una aplicación nativa en diferentes plataformas. Si bien los desarrolladores front-end expertos se han sintonizado con el desarrollo de varias plataformas híbridas que prometen ayudar a resolver este problema, Ionic Framework y Firebase son un dúo dinámico que, en conjunto, realmente nos brindan una flexibilidad increíble en la creación de aplicaciones para teléfonos inteligentes en tiempo real utilizando JavaScript y HTML5. .

Este tutorial presenta las capacidades de estas herramientas de desarrollo móvil multiplataforma e incluso proporciona algunos ejemplos de Ionic y Firebase.

Combinados, Ionic y Firebase son una excelente solución de desarrollo multiplataforma.

(Nota: este artículo asume cierta familiaridad con los conceptos básicos del marco AngularJS. Aquí hay una excelente publicación introductoria sobre AngularJS para aquellos que no tienen esa experiencia).

Introducción al marco iónico

El Ionic Framework consta de tres componentes principales:

  1. Un marco de interfaz de usuario basado en SASS diseñado y optimizado para interfaces de usuario móviles.
  2. Un marco JavaScript front-end de AngularJS que se utiliza para crear rápidamente aplicaciones escalables y rápidas.
  3. Un compilador (Cordova o PhoneGap) para aplicaciones móviles nativas con CSS, HTML y JavaScript.

El marco Ionic también está repleto de muchos componentes CSS útiles listos para usar.

Felicitaciones a Ionic por proporcionar una extensa documentación, ejemplos y videos de inicio para ayudar a simplificar la curva de aprendizaje y poner a los desarrolladores en funcionamiento rápidamente.

Presentamos Firebase

Firebase es un sistema de datos sin esquema de back-end como servicio que proporciona sincronización de datos en tiempo real sin necesidad de escribir ningún código personalizado. Firebase hace que gran parte de su desarrollo de back-end quede obsoleto, lo que reduce significativamente el tiempo de desarrollo multiplataforma.

Las características y beneficios clave incluyen:

  1. Cambios de datos sin cambios de código. Todos los cambios de datos se publican en los clientes de inmediato, sin necesidad de modificar el código de back-end.
  2. Muchos adaptadores. Hay adaptadores, con buen soporte y documentación, para todos los marcos de JavaScript populares y SDK de plataformas móviles. (Usamos AngularFire, que es el enlace de AngularJS para Firebase, en este artículo).
  3. Facilidad de autenticación. La autenticación en Firebase es tan simple como llamar a un único método, independientemente del método de autenticación. Admite inicios de sesión basados ​​en correo electrónico y contraseña simples, Google, Facebook, Twitter o Github.
  4. Desconectado habilitado. Todos los datos de Firebase están habilitados sin conexión, por lo que una aplicación puede ser completamente funcional (o casi completamente) en modo desconectado. Las aplicaciones se sincronizan automáticamente cuando se restablece la conexión.
  5. Tablero de configuración. Gran parte de Firebase (reglas de seguridad, por ejemplo) se puede configurar fácilmente a través de la interfaz de panel intuitiva de Firebase.
  6. Centrado en JSON. En Firebase, todos los datos se almacenan y recuperan en forma de objetos JSON.

Firebase también ofrece servicios en la nube para alojar el código front-end, lo que puede ahorrar mucho tiempo en la implementación y el mantenimiento.

También vale la pena señalar que Google adquirió Firebase en octubre pasado, lo que le ha brindado una atención y visibilidad significativamente mayores.

Un ejemplo de caso de uso simple: seguimiento de gastos

Los compañeros de cuarto a menudo comparten los gastos y dependen unos de otros en momentos de necesidad. Por lo tanto, ayudemos a los compañeros de cuarto a llevar un registro de sus gastos y ayudarlos a reconciliarse al final del mes.

Para hacer las cosas aún más interesantes, construyamos una aplicación móvil multiplataforma que proporcionará actualizaciones en tiempo real, para que cada uno pueda monitorear los gastos a medida que ocurren.

Este ejemplo de Ionic y Firebase demuestra un desarrollo fluido de aplicaciones multiplataforma.

Ahora que hemos decidido lo que queremos construir y nos han presentado las herramientas, ¡comencemos!

Primeros pasos con Ionic y Firebase

Lo primero que tenemos que hacer es instalar Ionic. Siga las instrucciones de instalación proporcionadas en la página de inicio de Ionic. (Tenga en cuenta que Ionic depende de NodeJS, por lo que las instrucciones requerirán que también lo instale si aún no lo tiene en su máquina).

El tutorial de 5 minutos de AngularFire es un excelente lugar para comenzar a familiarizarse con Firebase. Y si eres un "trabajador" o un aprendiz táctil como yo, es posible que desees extraer mi implementación de GitHub y comenzar a jugar con el código.

Codificando nuestra aplicación multiplataforma

Para este tutorial, vamos a utilizar la aplicación de tabs de muestra proporcionada como parte de la instalación de Ionic como base para nuestra aplicación. (Puede ejecutar la aplicación de muestra con el comando ionic start myApp tabs ).

Abra la aplicación de tabs de muestra en su IDE favorito (estoy usando Webstorm) y comencemos a modificarla para crear nuestra aplicación Roommates.

Para nuestra aplicación de ejemplo Ionic y Firebase, necesitaremos las siguientes tres pantallas:

Pantalla iónica/Firebase 1Pantalla iónica/Firebase 2Pantalla iónica/Firebase 3

Antes de crear estas pantallas, eliminemos la "Pantalla de detalles de amigos" proporcionada de manera predeterminada con la aplicación de muestra de la siguiente manera:

  1. Elimine el archivo www/templates/friend-detail.html .
  2. En www/js/app.js , elimine (o comente) el estado de friend-detail.html .
  3. En www/js/controllers.js , elimine el controlador FriendDetailCtrl al que se hace referencia en el estado que eliminamos.

Ahora cambiemos los íconos y el texto de los selectores de pestañas en la parte inferior de nuestra pantalla para que sean los siguientes:

Cambie los íconos y el texto de la pestaña usando este código de ejemplo para el marco Ionic.

Esto se hace simplemente haciendo los siguientes cambios en www/templates/tabs.html :

 <ion-tabs class="tabs-icon-top"> <!-- My Tab --> <ion-tab title="My Expense" icon="icon ion-log-in" href="#/tab/dash"> <ion-nav-view name="tab-dash"></ion-nav-view> </ion-tab> <!-- Friends Tab --> <ion-tab title="Roomie's" icon="icon ion-log-out" href="#/tab/friends"> <ion-nav-view name="tab-friends"></ion-nav-view> </ion-tab> <!-- Account --> <ion-tab title="Account" icon="icon ion-ios7-gear" href="#/tab/account"> <ion-nav-view name="tab-account"></ion-nav-view> </ion-tab> </ion-tabs>

Antes de conectar nuestros datos a Firebase, creemos una lista y vinculémosla a una matriz llamada expenses agregando el siguiente código a www/templates/tab-dash.html :

 <ion-view title="My Expenses"> <ion-content> <ion-list> <ion-item ng-repeat="expense in expenses|filter:user.password.email" type="item-text-wrap"> {{expense.label}} <span class="badge badge-balanced">{{expense.cost}}</span> </ion-item> </ion-list> <div class="card assertive"> <div class="item item-text-wrap"> Total Spent <span class="badge badge-positive">{{getTotal()}}</span> </div> </div> </ion-content> <ion-footer-bar> <input ng-model='label' type='text' placeholder='Type a new expense...' /> <input ng-model='cost' type="number" placeholder='$' /> <button class="button icon-left ion-plus" ng-click="addExpense($event)">Add</button> </ion-footer-bar> </ion-view>

También necesitaremos extender DashCtrl en www/js/controllers.js para incluir la matriz de expenses , así como un método addExpense y un método getTotal , de la siguiente manera:

 .controller('DashCtrl', function($scope) { $scope.expenses = [{ by: 'email', label: 'test', cost: 10 }]; $scope.addExpense = function(e) { $scope.expenses.push({ by: < some email > label: $scope.label, cost: $scope.cost }); $scope.label = ""; $scope.cost = 0; }; $scope.getTotal = function() { var rtnTotal = 0; for (var i = 0; i < $scope.expenses.length; i++) { rtnTotal += $scope.expenses[i].cost; } return rtnTotal; }; })

La matriz de expenses es lo que almacena los elementos en la lista de gastos, el método addExpense() agrega un nuevo valor a la matriz de expenses y el método getTotal() nos da el total de todos los elementos de la matriz.

Ahora es necesario realizar un conjunto similar de cambios en tab-friends.html . Intente hacer esto por su cuenta, pero si tiene problemas o desea verificar que lo haya hecho correctamente, puede consultar mi implementación en GitHub.

Conexión en Firebase

Necesitará una cuenta de Firebase. Puede registrarse aquí para obtener un "Plan Hacker" gratuito de Firebase.

Una vez que se registre, recibirá su URL raíz , que se parecerá a https://<yourfirebase>.firebaseio.com .

Habilitar Firebase en nuestra aplicación requiere dos modificaciones pequeñas para nuestra aplicación.

Primero, debemos incluir los scripts de Firebase en el archivo www/index.html de la aplicación de la siguiente manera:

 <script src='https://cdn.firebase.com/js/client/1.1.1/firebase.js'></script> <script src='https://cdn.firebase.com/libs/angularfire/0.8.0/angularfire.min.js'></script> <script src="js/app.js"></script>

A continuación, debemos agregar el módulo Firebase a nuestra aplicación agregando 'firebase' a la lista en nuestro módulo 'starter' AngularJS:

 angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'firebase'])

Firebase ahora está habilitado, como cualquier otro módulo de AngularJS.

El tutorial de 5 minutos de AngularFire le enseñará a crear referencias de datos en los controladores. Sin embargo, para nuestra aplicación de demostración, decidí mantener estas referencias en un servicio separado (ya que esto hace que sea mucho más fácil de mantener y actualizar si se cambia la URL raíz). Para crear este servicio, agregue lo siguiente a www/js/services.js :

 .factory('fireBaseData', function($firebase) { var ref = new Firebase("https://luminous-fire-3429.firebaseio.com/"), refExpenses = new Firebase("https://luminous-fire-3429.firebaseio.com/expenses"), refRoomMates = new Firebase("https://luminous-fire-3429.firebaseio.com/room-mates"); return { ref: function() { return ref; }, refExpenses: function() { return refExpenses; }, refRoomMates: function() { return refRoomMates; } } });

El código anterior agrega tres URL de referencia. Uno para la raíz y dos para los cobros que hemos denominado expenses y room-mates .

Agregar una nueva colección a Firebase simplemente se hace agregando su nombre al final de su URL raíz . Entonces, para crear la colección de expenses que necesitaremos, todo lo que necesitamos es lo siguiente:

https://<yourfirebase>.firebaseio.com/expenses

Esto creará la colección de expenses , y luego podemos comenzar a agregarle objetos.

Bien, ahora podemos conectar la colección de gastos de Firebase para reemplazar la matriz de gastos "ficticia" que creamos anteriormente. Esto se hace modificando DashCtrl en www/js/controllers.js de la siguiente manera:

 .controller('DashCtrl', function($scope, fireBaseData, $firebase) { $scope.expenses = $firebase(fireBaseData.refExpenses()).$asArray(); $scope.addExpense = function(e) { $scope.expenses.$add({ by: < someemail > , label: $scope.label, cost: $scope.cost }); $scope.label = ""; $scope.cost = 0; }; $scope.getTotal = function() { var rtnTotal = 0; for (var i = 0; i < $scope.expenses.length; i++) { rtnTotal += $scope.expenses[i].cost; } return rtnTotal; }; })

Es necesario realizar un conjunto similar de cambios en FriendsCtrl . Nuevamente, le recomiendo que intente hacer esto por su cuenta, pero si tiene problemas o desea verificar que lo haya hecho correctamente, puede consultar mi implementación en GitHub.

Para verificar que funciona, mientras ejecuta la aplicación en dos clientes diferentes, agregue un nuevo gasto y vea que aparece en la lista en ambos clientes. Si funciona... ¡guau! ¡Ya ha conectado con éxito su aplicación Ionic con Firebase!

Puede probar su aplicación multiplataforma en diferentes dispositivos conectando un dispositivo a su sistema y ejecutando ionic run android o ionic emulate ios . Consulte la documentación de Ionic para obtener más información sobre cómo probar su aplicación.

Gestión de cuentas y seguridad con Firebase

Aunque la funcionalidad básica ahora funciona, un problema grave es que nuestra aplicación actualmente es completamente insegura. Todo el mundo puede ver sus gastos, sin necesidad de permisos ni inicios de sesión. Esto obviamente necesita ser abordado.

Firebase proporciona un marco de autenticación poderoso pero simple usando "reglas". Se pueden hacer muchas cosas con el lenguaje de reglas de Firebase. (Consulte la documentación de seguridad de Firebase para obtener más detalles).

En nuestro caso, escribiremos una regla muy simple para bloquear el acceso de usuarios no autorizados a nuestros datos. Para hacer esto, abra su URL raíz, haga clic en "Seguridad y reglas" en la barra de acción izquierda, pegue el código a continuación en sus reglas y haga clic en Guardar.

 { "rules": { ".read": "auth != null", ".write": "auth != null" } }

Si ejecuta su aplicación ahora, notará que no hay datos. Incluso puede intentar inspeccionar su solicitud utilizando las herramientas del navegador y debería ver un mensaje en su consola que indica que no está autorizado para ver los datos.

Creación de cuentas de usuario y activación del inicio de sesión

Puede autenticar a sus usuarios permitiéndoles crear su propia combinación de correo electrónico y contraseña, o usar cualquiera de sus credenciales de inicio de sesión existentes de Google, Facebook, Twitter o Github. Para la autenticación de correo electrónico/contraseña, Firebase ofrece un conjunto completo de métodos API para cambiar, restablecer, etc., la contraseña. Puede encontrar más información sobre la autenticación con Firebase en la guía de Firebase.

Para nuestra aplicación de demostración, crearemos dos cuentas de usuario a través de la interfaz de Firebase. Esto se puede hacer yendo a su URL raíz de Firebase y haciendo lo siguiente:

  1. Haga clic en Inicio de sesión y autenticación en la barra de acción del lado izquierdo.
  2. Seleccione la casilla de verificación para habilitar la autenticación de correo electrónico y contraseña.
  3. Desplácese hacia abajo para encontrar el "Formulario Agregar nuevas cuentas"
  4. Agregue sus cuentas usando "Agregar nuevo usuario".

Habilitar inicios de sesión seguros es esencial cuando se desarrollan aplicaciones multiplataforma con Ionic y Firebase.

Para habilitar la interfaz de inicio de sesión para sus usuarios, primero agregue el siguiente código a www/templates/tab-account.html :

 <ion-view title="Account"> <ion-content> <div class="list" ng-show="showLoginForm"> <label class="item item-input"> <span class="input-label">Email</span><input type="text" ng-model="em"/> </label> <label class="item item-input"> <span class="input-label">Password</span><input type="password" ng-model="pwd"/> </label> <button class="button button-block button-positive" ng-click="login(em, pwd)">Login</button> </div> <div class="card" ng-hide="showLoginForm"> <div class="item item-text-wrap">You are logged in as {{user.password.email}}</div> </div> <button class="button button-stable" ng-click="logout()" ng-hide="showLoginForm">Logout</button> </ion-content> </ion-view>

Luego agregue lo siguiente a AccountCtrl en www/controller.js :

 .controller('AccountCtrl', function($scope, fireBaseData) { $scope.showLoginForm = false; //Checking if user is logged in $scope.user = fireBaseData.ref().getAuth(); if (!$scope.user) { $scope.showLoginForm = true; } //Login method $scope.login = function (em, pwd) { fireBaseData.ref().authWithPassword({ email : em, password : pwd },function(error, authData) { if (error === null) { console.log("User ID: " + authData.uid + ", Provider: " + authData.provider); $scope.user = fireBaseData.ref().getAuth(); $scope.showLoginForm = false; $scope.$apply(); } else { console.log("Error authenticating user:", error); } }); }; // Logout method $scope.logout = function () { fireBaseData.ref().unauth(); $scope.showLoginForm = true; }; });

Una cosa importante a tener en cuenta desde el punto de vista de la seguridad es que los inicios de sesión de Firebase son persistentes de forma predeterminada . Por lo tanto, si desea que su usuario necesite iniciar sesión cada vez que se inicia la aplicación, deberá modificar la configuración de Firebase en consecuencia. Para hacer esto, solo una vez después de un inicio de sesión exitoso, ejecute el siguiente código:

 var r = $firebase(fireBaseData.refRoomMates()).$asArray(); // NOTE: Substitute the email addresses of your two user accounts in the line below r.$add(["[email protected]","[email protected]"]);

Puede agregar esto en el controlador de cuenta después de un inicio de sesión exitoso, o poner un punto de interrupción después de un inicio de sesión exitoso y ejecutarlo en el inspector de su consola.

Filtrado basado en el usuario

Sin embargo, a la aplicación móvil multiplataforma aún le falta una característica importante. Queremos distinguir tus gastos de los de tu compañero de piso. Ahora que hemos creado dos cuentas, solo necesitamos filtrar los datos en nuestras vistas.

Primero debemos modificar dashCtrl en www/js/controllers.js para (a) obtener los datos del usuario actual en $scope y (b) ahorrar cualquier gasto adicional para el usuario actual:

 .controller('DashCtrl', function($scope, fireBaseData, $firebase) { $scope.expenses = $firebase(fireBaseData.refExpenses()).$asArray(); $scope.user = fireBaseData.ref().getAuth(); // ADD MESSAGE METHOD $scope.addExpense = function(e) { $scope.expenses.$add({ by: $scope.user.password.email, label: $scope.label, cost: $scope.cost }); $scope.label = ""; $scope.cost = 0; }; $scope.getTotal = function () { var rtnTotal = 0; for (var i = 0; i < $scope.expenses.length; i++) { rtnTotal += $scope.expenses[i].cost; } return rtnTotal; }; })

A continuación, debemos agregar un filtro en www/templates/tab-dash.html para mostrar solo los gastos del usuario actual:

 <ion-item ng-repeat="expense in expenses|filter:user.password.email" type="item-text-wrap">

Bien, la pantalla de inicio ahora es perfecta. Un usuario solo puede ver y agregar sus propios gastos.

El último y último paso es permitir compartir la lista completa de gastos entre compañeros de cuarto. Para hacerlo, cambie www/templates/tab-friends.html para agregar este filtro:

 <ion-item ng-repeat="expense in expenses|filter:roomiesEmail" type="item-text-wrap">

Luego modifique FriendsCtrl en www/controllers.js de la siguiente manera:

 .controller('FriendsCtrl', function($scope, fireBaseData, $firebase) { $scope.user = fireBaseData.ref().getAuth(); $scope.expenses = $firebase(fireBaseData.refExpenses()).$asArray(); $scope.roomies = $firebase(fireBaseData.refRoomMates()).$asArray(); $scope.roomies.$loaded().then(function(array) { //array = [[set1_rm1_email, set1_rm2_email], [set2_rm1_email, set2_rm2_email] ...] for (var i = 0; i < array.length; i++) { if (array[i][0] === $scope.user.password.email) { $scope.roomiesEmail = array[i][1]; } else if (array[i][1] === $scope.user.password.email) { $scope.roomiesEmail = array[i][0]; } } $scope.$apply(); // NOTE: For simplicity, this demo only supports the 2-roommate use case }); $scope.addExpense = function(e) { $scope.expenses.$add({ by: $scope.roomiesEmail, label: $scope.label, cost: $scope.cost }); $scope.label = ""; $scope.cost = 0; }; $scope.getTotal = function () { var rtnTotal = 0; for (var i = 0; i < $scope.expenses.length; i++) { rtnTotal += $scope.expenses[i].cost; } return rtnTotal; }; })

¡Eso es todo! Instale/actualice la aplicación tanto en su dispositivo como en el dispositivo de su compañero de cuarto y ¡debería estar listo!

Envolver

Nuestro ejemplo simple solo comienza a arañar la superficie de lo que se puede lograr, y con qué facilidad se puede lograr, utilizando Ionic y Firebase. Realmente son un dúo poderoso para crear aplicaciones de teléfonos inteligentes multiplataforma en tiempo real utilizando JavaScript y HTML5.

Relacionado: Tutorial de Angular 6: nuevas funciones con nueva potencia (un ejemplo de pila completa que incluye un back-end de Firebase)