Firebase para aplicaciones Xamarin.Forms – Parte 3. FirebaseDataBase para Android

Continuamos con la implementación de Firebase en nuestra aplicación de Xamarin.Forms, y tras implementar la autenticación en iOS (http://albertomontesdeoca.xyz/firebase-para-aplicaciones-xamarin-forms-parte-2-firebaseauth-para-ios/) y en Androd (http://albertomontesdeoca.xyz/firebase-para-aplicaciones-xamarin-forms-parte-1-firebaseauth-para-android/), continuamos con la implementación de la base de datos remota de Firebase en Android.

Configurando nuestro proyecto Xamarin.Forms

Lo primero que haremos será agregar a nuestro proyecto los paquetes Nugets necesarios para poder disfrutar de Firebase Database en nuestro proyecto, para ello buscamos el paquete “Xamarin.Firebase.Database“.

 

A continuación crearemos el servicio en nuestro proyecto PCL y que posteriormente implementaremos en cada una de las plataformas.

Configurando la aplicación

Lo primero que debemos hacer antes de nada es configurar nuestra aplicación para poder usar las características de la base de datos de Firebase.
Para ello en la clase MainActivity de nuestro proyecto Android debemos especificar la url de nuestra base de datos, que encontrareis en vuestra consola de Firebase.

private void InitFirebaseAuth()
{
   var options = new FirebaseOptions.Builder()
   .SetApplicationId("1:2485447395:android:1bf7180db061f771")
   .SetApiKey("AIzaSyBdszK9ZCwbukS8Qb1iZ_LCXVq2os-KYJA")
   .SetDatabaseUrl("https://fir-sample-d9469.firebaseio.com")
   .Build();

    if (app == null)
       app = FirebaseApp.InitializeApp(this, options, "FirebaseSample");

}

Definición del servicio

Al igual que para el servicio de autenticación, crearemos un servicio llamado IFirebaseDBService con la siguiente estructura.

using System;
namespace firebasesample.Services.FirebaseDB
{
    public interface IFirebaseDBService
    {
        void Connect();
        void GetMessage();
        void SetMessage(String message);
        String GetMessageKey();
    }
}

Actualizando la Interfaz

Una vez que hemos creado el servicio, actualizaremos la interfaz de nuestra aplicación.

Para ello simplemente en nuestra pantalla de bienvenida (MainView) crearemos una caja de texto y un botón para mostrar el mensaje y poder grabarlo.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="firebasesample.Views.Main.MainView">
    <ContentPage.Content>
        <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
        <Label Text="Welcome Firebase-Sample. You are login!" VerticalOptions="Center" HorizontalOptions="Center" />
        <Entry VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Text="{Binding Message}"/>
         <Button Text="Save" Command="{Binding SaveTextCommand}" BackgroundColor="#1FBED6" HorizontalOptions="Fill" TextColor="White" />
        <Button Text="Logout" Command="{Binding LogoutCommand}" BackgroundColor="#1FBED6" HorizontalOptions="Fill" TextColor="White" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

En el ViewModel correspondiente realizaremos las siguiente actualizaciones.

  • Accederemos al servicio IFirebaseDBService
    private IFirebaseDBService _firebaseDatabaseService;
    
  • En el constructor, nos conectaremos a la base de datos y obtendremos el mensaje
    _firebaseDatabaseService = DependencyService.Get<IFirebaseDBService>();
    _firebaseDatabaseService.Connect();
    _firebaseDatabaseService.GetMessage();
    MessagingCenter.Subscribe<String, String>(this, _firebaseDatabaseService.GetMessageKey(), (sender, args) =>
    {
        Message  = (args);
    
    });
    

Como veis volvemos a usar suscripción a mensaje al igual que lo hicimos con login de Google.

A continuación procederemos con la implementación del servicio en Android.

Implementando el Servicio

Al igual que se hizo con el servicio IFirebaseAuthService, usaremos la inyección de dependencias para implementar nuestro recién creado servicio IFirebaseDBService, para ello lo primero que haremos será definir nuestra clase:

using System;
using System;
using System.Threading.Tasks;
using firebasesample.Droid.Services.FirebaseAuth;
using firebasesample.Services.FirebaseAuth;
using Xamarin.Forms;
using Firebase.Auth;
using Android.App;
using Android.Content;
using firebasesample.Droid.Activities;
using firebasesample.Droid.Services.FirebaseDB;
using firebasesample.Services.FirebaseDB;
using Firebase.Database;

[assembly: Dependency(typeof(FirebaseDBService))]
namespace firebasesample.Droid.Services.FirebaseDB
{
    

    public class FirebaseDBService : IFirebaseDBService
    {
        
        public void Connect()
        {
            throw new NotImplementedException();
        }

        public void GetMessage()
        {
            throw new NotImplementedException();
        }

        public string GetMessageKey()
        {
           throw new NotImplementedException(); 
        }

        public void SetMessage(string message)
        {
            throw new NotImplementedException();
        }
    }
}

Conectar la base de datos

Para ello implementamos el método Connect

FirebaseDatabase database;

public void Connect()
{
    database = FirebaseDatabase.GetInstance(MainActivity.app);
}

Obtener mensaje

Para ello implementamos el método GetMessage.

La estructura que hemos definido para los mensajes es muy sencilla, un mensaje por cada usuario.

public void GetMessage()
{
    var userId = authService.GetUserId();
    databaseReference = database.GetReference("messages/" + userId);
    databaseReference.AddValueEventListener(new ValueEventListener());
    
}

Como podeis comprobar, aqui nos encontramos con algo nuevo la clase ValueEventListener. Esta clase es la encargada de recibir los eventos cada vez que el valor de nuestra base de datos se actualiza tanto desde dentro como desde fuera de la aplicación.

Esta clase la implementaremos como interna dentro de nuestro servicio.

public class ValueEventListener : Java.Lang.Object, IValueEventListener
{
    public void OnCancelled(DatabaseError error) { }

    public void OnDataChange(DataSnapshot snapshot) {
        String message = snapshot.Value.ToString();
        MessagingCenter.Send(FirebaseDBService.KEY_MESSAGE, FirebaseDBService.KEY_MESSAGE, message);
            
        
    }
}

Establecer mensaje

Para ello implementamos el método SetMessage.

public void SetMessage(string message)
{
    var userId = authService.GetUserId();
    databaseReference = database.GetReference("messages/" + userId);
    databaseReference.SetValue(message);
}

Como veis el actualizar el mensaje es algo muy sencillo.

Conclusión

Hemos trabajado con una estructura de datos muy sencilla, pero la idea es la misma si usáramos una base de dato más compleja.

Para probar la actualización desde fuera podéis probar a actualizar el valor desde otro dispositivo logado con el mismo usuario o bien modificar el valor de vuestro mensaje directamente desde la consola de Firebase.

Espero que os haya sido útil y nos vemos en el próximo artículo con la implementación del servicio de datos para iOS.

Recordad que podeis descargar el código fuente completo desde el siguiente repositorio de GitHub: https://github.com/jamontes79/xamarin-forms-firebase-sample
 

Publicado en Desarrollo, Xamarin y etiquetado , , , , .

Ingeniero Técnico en Informática de Sistemas. Apasionado de la tecnología y enfocado al desarrollo móvil

12 Comentarios

  1. Pingback: Firebase para aplicaciones Xamarin.Forms – Parte 4. FirebaseDataBase para iOS – Alberto Montes de Oca

    • Buenos días lujan, muchas gracias por tu comentario, para borrar un item de un array en database sería de la siguiente forma:

      database.GetReference("id_a_eliminar").RemoveValue();

      Si tienes alguna otra duda y puedo ayudarte estaré encantado de hacerlo.

      Un saludo

  2. gracias por la contestacion, pero apuntando a la referencia y haciendo el removeValue() no me funciona, creo que eso funciona para cualquier dato al igual que haciendolo .setValue(null); pero para el tema del array me parece que tengo que poner el index del dato a borrar, hare unas pruebas y si encuentro la solucion la pondré por si le puede servir a otro.

  3. public void deleteEvent(View view) {

    eventos = new ArrayList();

    databaseReference = FirebaseDatabase.getInstance().getReference(“Users”).child( uiD );
    databaseReference.addListenerForSingleValueEvent( new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {

    User listas =dataSnapshot.getValue(User.class);
    eventos=listas.getevents();

    for( int i=0; i<listas.getevents().size();i++){
    if(eventos.get( i ).equals( code )){
    eventos.remove( i );
    users.getevents().remove( i );

    databaseReference.setValue( users );
    }
    if (eventos.contains( code )){
    eventos.remove( code );
    }

    }

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
    } );

    }

  4. Hola como estas! Gracias por el tutorial. Estoy teniendo algunos inconvenientes que no estoy pudiendo resolver quizás me puedes ayudar.

    estoy intentando ejecutar

    var databaseReference = database.GetReference(“offers”);
    databaseReference.Child(“1”).SetValue(new Offer(“bozo”, 100));

    Y la segunda linea me tira el siguiente error

    Firebase.Database.DatabaseException: No properties to serialize found on class md5aa6bb7e849e00eeb0a0e3205ce90cebe.Offer……..

    Mi clase Offer es la siguiente

    public class Offer:Java.Lang.Object
    {
    public String name;
    public Double price;

    public Offer(){

    }

    }

    Gracias

    • Hola, antes de nada gracias por tu comentario y perdona por no haber contestado antes, he estado algo liado y no he podido dedicarle tiempo al blog.

      En respuesta a tu pregunta tenemos dos opciones, cambiar tus variables por getters y setters:

      public string Name { get; set; }
      public Double Price { get; set; }

      o bien almacenar hacer el SetValue en lugar de un objeto de un json, yo personalmente soy partidario de la segunda opción, no estoy seguro si para esta opción también es necesario crear los getters y setters aunque yo los creo.

      El código te quedaría de la siguiente forma:

      string json = JsonConvert.SerializeObject(new Offer(“bozo”, 100));
      databaseReference.Child(“1”).SetValue.SetValue(json);

      Ya me cuentas si te ha funcionado.

      Un saludo y de nuevo gracias por tu comentario.

  5. hola alberto

    Primero, muchas gracias por el artículo.

    No puedo reproducir el funcionamiento del botón “Guardar”. Cuando lo presiono, nada sucede en mi base de datos. ¿Debo crear algo en la consola del firebase?

    La autenticación funcionó perfectamente.

    • Hola Wélington, antes de nada muchas gracias por tu comentario.

      Se me ocurren dos cosas:
      – ¿Has creado la base de datos en la consola de Firebase como se indica en el punto “Configurando la aplicación”?
      – ¿El fichero json con la configuración está actualizado con esta información?
      – Supongo que si, ¿pero has probado a debugar y comprobar que te está entrando por el método correspondiente?

      Asi de pronto no se me ocurre otra cosa. ¿Te da algún error?

      Ya me dices si te ha funcionado.

      Un saludo
      Gracias

  6. Hola Alberto, muy buena tu explicación!!!!
    tengo una consulta, tengo un proyecto xamarin que por ahora guarda la base de datos JSon localmente, en el celular o en el emulador, lo que quiero hacer es que la base la pueda guardar en firebase, puedo enviar el archivo json a firebase? o tengo que tener un json en firebase igual al local?
    como puedo hacer para que la app guarde, actualice y borre en el json que esta firebase por favor? me darias una mano, estoy medio perdido….muchísimas gracias!
    ya asocie el firebase a la app pero no se como instanciar e interactuar con la base…
    un saludo

    • Perdoname Fabricio, he tenido algo desatendida la web los últimos meses, no termino de entender tu pregunta. Firebase guarda la base de datos en la nube, para que tengas acceso a tus datos sin tener conexión debes activar la persistencia de datos usando setPersistenceEnabled al obtener la instancia de la base de datos. Espero que te haya servido de ayuda.

      Un saludo

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.