Menu

Sincronización Offline con AngularFire

firebaseionic - August 10, 2017 por Jorge Vergara
ionic3.6.0ionic-native3.12.1ionic-app-scripts2.1.3cordova-cli7.0.1ionic-cli3.6.0

Una de las preguntas que mas me hacen es como hacer para tener Firebase trabajando de manera Offline con Ionic Apps, Para cuando los usuarios estan en conexiones inestables.

Yo siempre respondo de la misma manera, “Estoy esperando a que Firebase agregue soporte oficial a su JS SDK para poder usarlo” pero enfrentemoslo, esta ha sido una larga espera y aún nada.

Buscando un poco encontre una libreria interesante y facil de usar llamada AngularFire2 Offline por Adrian Carriger.

He estado jugando con ella por unos dias, y he encontrado que es muy facil de usar, y lo mejor es que no tienes que hacer grandes configuraciones o cambios para tenerla funcionando.

Con esa introducucción vamos a programar.

AngularFire2 Offline

Lo primero que debes hacer es instalar la libreria ( Asumiendo que tu ya tienes una App en Ionic creada estas ubicado en el directorio de la App ), Solo abre la terminar y ejecuta.

$ npm install angularfire2-offline angularfire2 firebase --save

Si estas usando npm 5+ puedes remover el –save, este lo hace automaticamente.

Una vez este instalado, ve al archivo app.module.ts, importe e inicialice ambos AngularFire2 y AngularFire2 Offline:

import { AngularFireModule } from 'angularfire2';
import { AngularFireOfflineModule } from 'angularfire2-offline';
import { AngularFireDatabaseModule } from 'angularfire2/database';

export const firebaseConfig = {
  apiKey: "Your Firebase Credentials",
  authDomain: "Your Firebase Credentials",
  databaseURL: "Your Firebase Credentials",
  projectId: "Your Firebase Credentials",
  storageBucket: "Your Firebase Credentials",
  messagingSenderId: "Your Firebase Credentials"
};

@NgModule({
  declarations: [...],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp),
    AngularFireModule.initializeApp(firebaseConfig),
    AngularFireDatabaseModule,
    AngularFireOfflineModule
  ],
  bootstrap: [IonicApp],
  entryComponents: [...],
  providers: [...]
})
export class AppModule {}

Notese como hemos agregado el AngularFireOfflineModule a la declaracion de entrada.

Ahora que nuestra app esta inicializada nosotros podemos empezar a jugar con la libreria, vamos dentro del home.html y muestre una lista simple de canciones, la idea es que la lista persista aun si quedamos Offline y tenemos una actualización.

<ion-header>
  <ion-navbar>
    <ion-title>
      Playlist
    </ion-title>
    <ion-buttons end>
      <button ion-button icon-only (click)="addSong()">
        <ion-icon name="add"></ion-icon>
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-list>
    <ion-item *ngFor="let item of items | async">
      
    </ion-item>  
  </ion-list>
</ion-content>

Estamos mostrando la lista dentro de nuestras etiquetas <ion-content></ion-content y estamos agregando un pequeño boton a la barra de navegación para agregar nuevas canciones a nuestra lista.

Nosotros crearemos canciones nuevas offline, y se sincronizaran con la base de datos una vez volvamos online.

Ahora vemos que toda la funcionalidad esta funcionando, mueve el home.ts e importa todo lo que necesites:

import { Component } from '@angular/core';
import { NavController, AlertController } from 'ionic-angular';

import { 
  AfoListObservable, 
  AngularFireOfflineDatabase } from 'angularfire2-offline/database';

La cosa genial sobre esta libreria offline es que tiene los mismos metodos que Angularfire2 tiene, Asi que los nombres son los mismos.

Para obtener nuestro HTML trabajando y mostrar la lista todo lo que necesitamos es crear una lista Observable de la base de datos.

public items: AfoListObservable<any[]>;
constructor(afoDatabase: AngularFireOfflineDatabase, 
    public alertCtrl: AlertController) {
    this.items = afoDatabase.list('/items');
}

No hemos hecho nada distinto a lo que hacemos con el AngularFire2 normal, y ya tenemos persistencia offline para nuestros datos, prueba guardando algunos datos y desconecta el Internet y haz una actualización, veras los datos aun ahi.

Ahora si queremos agregar las canciones a la lista, Nosotos usamos la función .push normal de AngularFire2.

addSong(): void {
  const prompt = this.alertCtrl.create({
    title: 'Add Song',
    message: "Add a new song to your playlist",
    inputs: [
      {
        name: 'songName',
        placeholder: 'Song Name'
      },
    ],
    buttons: [
      {
        text: 'Cancel',
        handler: data => {
          console.log('Cancel clicked');
        }
      },
      {
        text: 'Save',
        handler: data => {
          this.items.push({
            songName: data.songName
          });
        }
      }
    ]
  });
  prompt.present();
}

Nosotros solo empujamos la canción con una propiedad: songName. Esta es la manera exacta para empujar objetos a una lista en AngularFire2, ahora vamos y desconectemos el internet y agrega una canción veras que la canción aparece inmediatamente en tu lista.

Y si ves la base de datos tu veras que la canción no esta allí (duh, estamos desconectados), vamos a actualizar la vista, veras que la nueva canción aún aparece ahi, conectate a Internet y revisa tu base de datos 🙂

Para tener en cuenta.

Algunas cosas para tener en cuenta:

  • Los mismos metodos, es verdad, eso significa que puedes hacer consultas, trabajar con listas, objetos, CRUD, etc. Todo lo cual tiene sincronización offline.

  • preserveSnapshot no esta soportada.

  • Si escribes estando offline seguido por una actualización, las actualizaciones seran enviadas cuando tengas una conexion a Internet disponible.

Ver post original en Ingles.

¡Compártelo!