Android/Firebase

Què és Firebase Cloud Messaging?[modifica]

Fins ara, disposàvem de Google Cloud Messaging, el qual ens permet enviar missatges entre servidors i clients però, a causa que han desenvolupat una alternativa millor, aquest servei va ser discontinuatel 10 d’abril de 2018 i serà posteriorment eliminat el 11 d’abril del 2019 (donen un espai de temps per a què es pugui fer efectiva la migració de GCM al nou, FCM).

Firebase Cloud Messaging (FCM) com el seu propi nom indica, es una solució de missatgeria multiplataforma que ens permet enviar missatges de forma segura, gratuïta i ràpida. Com ens podem esperar, la missatgeria és tot en el que es basa FCM, per això tenim diversos modes d’enviament de missatges; a un dispositiu, a una sèrie de dispositius o inclús discriminant temes. Aquesta discriminació la podrem realitzar a la part del servidor on haurem de discriminar a qui enviem els missatges. Una vegada explicats quins son els seus objectius hi ha una sèrie de funcions que són clau:

  • Enviament de missatges de notificació o de dades. Envia missatges de notificació que es mostren al teu target. Gràcies a què és una funció que el programador pot implementar, es poden enviar missatges de dades i nosaltres decidir què fem amb el missatge a l'aplicació. Si es vol més informació sobre aquesta funció clau podeu anar a Tipus de missatges
  • Enviament de missatges des d'aplicacions client. Es caracteritza per l'enviament de missatges de confirmació, de xat i d'altres tipus des deels dispositius al teu servidor a través de la connexió que ofereix FCM.
Estructura de funcionament FCM

Aspectes tècnics[modifica]

Amb FCM tenim la possibilitat de notificar a una aplicació client que un nou correu electrònic o que altres dades es troben disponibles per la sincronització. A més, pots enviar missatges de notificació per tornar a atraure nous usuaris i augmentar la seva atenció. Pels casos pràctics de missatgeria instantània, un missatge pot transferir fins a una càrrega de 4 KB a una aplicació client.

Aquesta implementació FCM inclou dos components principals per rebre i enviar dades:

  1. Un entorn de confiança com Cloud Functions per Firebase o un servidor d'apps per generar, orientar i enviar missatges
  2. Una aplicació client d'iOS, Android o Web (Javascript) que rebi missatges.

Pots enviar, a més, missatges a través del SDK d'Admin o mitjançant les API de HTTP i XMPP. En cas de que es vulguin realitzar proves o enviar missatges de participació o de marketing amb orientació i anàlisis integrats potents, també pots usar el compositor de Notifications.

Migració d'una aplicació Android GCM a FCM[modifica]

Degut a la recent eliminació de Google Cloud Messaging es possible que s'hagi de fer la migració de moltes aplicacions a Firebase Cloud Messaging, per això es realitzará una guia pas a pas indicant quins son els pasos a seguir. Però, abans de començar s'hauran d'aclarar diverses qüestions:

  • Google Cloud Messaging i Firebase Cloud Messaging no poden coexistir en una mateixa aplicació
  • L'obtenció de tokens mitjançant GoogleCloudMessaging.register() o InstanceID.getToken() continuaran funcionant sense cap tipus de modificació

Una vegada això ho tenim clar, podem començar amb els passos a realitzar per el desenvolupador per arribar a completar la migració total de l'aplicació.

1. Importar el teu projecte GCM a un projecte FCM[modifica]

En aquest pas, com indica el títol realitzarem la migració del projecte. Per fer-ho, realitzarem el següent en l'ordre indicat:

  1. A la consola de Firebase selecciona Añadir Proyecto
  2. Selecciona el teu projecte GCM de la llista dels projectes Google Cloud i selecciona Firebase
  3. A la pantalla de benvinguda selecciona Añadir Firebase a tu aplicación Android
  4. Proporciona el teu nom de paquet i SHA-1 i selecciona Añadir App. Un nou fitxer google-services.json per la teva aplicació Firebase serà descarregat.
  5. Selecciona Continua i segueix les instruccions detallades per afegir el plugin de Google Services a Android Studio.

2. Canvia a FCM en el nivel d'aplicació build.gradle[modifica]

Nosaltres abans teniem una cosa com aquesta:

dependencies {

 compile "com.google.android.gms:play-services-gcm:15.0.1"

}

Com ens trobem a FCM aquest gcm ja no el necessitarem, per aquesta raó ho canviarem:

dependencies {

 compile "com.google.firebase:firebase-messaging:17.3.0"

}

3. Edita el manifest de la teva aplicació[modifica]

FCM afegirà automàticament totes les dependències, per això ens haurem d'assegurar que totes les dependències existents amb GCM s'eliminin de la nostre aplicació, ja que com s'ha comentat anteriorment les dues aplicacions no poden coexistir. Per aquesta raò, s'hauran d'eliminar aquestes parts del manifest:

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <permission android:name="<your-package-name>.permission.C2D_MESSAGE"
            android:protectionLevel="signature" />
    <uses-permission android:name="<your-package-name>.permission.C2D_MESSAGE" />
     ...
    <receiver
    android:name="com.google.android.gms.gcm.GcmReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <category android:name="com.example.gcm" />
    </intent-filter>
    </receiver>

4. Actualitza els endpoints del servidor[modifica]

Actualitza el codi del teu servidor per utitlizar els nous FCM endpoints per HTTP i XMPP. S'ha de tenir en compte que la versió nova de FCM de gcm-http.googleapis.com/gcm/ és fcm.googleapis.com/fcm/ (sense el http):

GCM endpoint FCM endpoint
gcm-http.googleapis.com/gcm/ fcm.googleapis.com/fcm/
gcm-xmpp.googleapis.com fcm-xmpp.googleapis.com

5. Pròxims passos i canvis migratoris opcionals[modifica]

Depenent de quins features s'estiguin utilitzant a la teva aplicació GCM s'hauran d'aplicar més canvis. És probable que la majoria d'aplicacions necessitin migrar un InstanceIDListenerService per treballar amb FCM.

Normalment requerit: migrar el teu InstanceIDListenerService[modifica]

Realitza aquest canvi si necessites accedir al token de la registració del dispositiu perquè:

Opcional: migrar el teu GcmListenerService[modifica]

Realitza aquest canvi si necessites controlar missatges entrants com poden ser:

  • La teva aplicació solament rep missatges amb informació rellevant
  • La teva aplicació rep notificacions de payload mentre la aplicació es troba executant-se en primer pla
  • La teva aplicació rep errors en cas d'errors en missatges upstream

Opcional: actualitza el ús de GcmPubSub[modifica]

Realitza aquest pas si:

  • Necessites subscriure nous dispositius a temes. Dispositius que ja es trobin subscrits abans de la migració continuaran rebent els missatges. Per exemple, un dispositiu subscrit a /temes/noticies a GCM seguirà rebent missatges de /noticies després de la migració a FCM (si ens fixem a FCM no es necessari especficiar /temes/, amb /noticies ho entèn).

Cas especial: migració d'un projecte GCM a un projecte FCM existent[modifica]

Realitza aquesta migració si:

  • Ja tens aquest projecte FCM en el que t'agradaria migrar l'aplicació GCM amb els seus usuaris. Aquesta situació requerirà tasques adicionals.

Implementació d'un cas pràctic FCM[modifica]

Per poder implementar la funcionalitat FCM haurem de disposar d'una versió 1.4 o superior d'Android Studio amb Gradle. A més, els clients de FCM hauran de tenir una versió d'Android superior a la 4.0 amb l'aplicació Google Play Store al seu sistema.

Abans de començar amb la configuració de l'aplicació client, haurem d'incorporar a Android Studio el Firebase. Per afegir-ho haurem de seguir els següents pasos:

Configura una aplicació client amb Firebase Cloud Messaging en Android[modifica]

Per afegir Firebase si tenim una versió superior a 2.2 d'Android Studio ho podrem realitzar amb Firebase Assistant, la qual es la forma més simple d'incorporar-ho. Aquest, podrà afegir-se al teu projecte o crear-ne un de nou amb totes les dependències afegides al Gradle.

En cas d'utilitzar versions anteriors a 2.2 s'haurà d'incorporar de forma manual al projecte.

1. Com utilitzar Firebase Assistant[modifica]

Per afegir Firebase Assistant fes el següent:

  • Fes click en Herramientas > Firebase per abrir la finestra Assistant.

Opcions a escollir en Tools

  • Fes click en Cloud Messaging, i fes click en el vincle del instructiu proporcionat Set up Firebase Cloud Messaging. Ens demanarà registrar-nos amb un compte gmail i, una vegada entrem, ja tindrem aquesta compte lligada amb Firebase per utilitzar els seus serveis.

Assistent de Firebase

  • Fes click en el botó Connect to Firebase.
  • Fes click en el botó Add FCM to your project.

Una vegada ens haguem connectat a Firebase i afegit FCM al nostre projecte haurem de veure-ho de la següent forma:

FCM afegit al projecte d'Android Studio


Una vegada s'ha fet això podrem realitzar l'aplicació.

2. Canvis en AndroidManifest.xml[modifica]

Degut a què estem afegint nous serveis al nostre projecte ens haurem d'anar al manifest de la nostra aplicació.

Localització del fitxer manifest

Per tal de implementar-ho correctament haurem d'afegir això al nostre AndroidManifest.xml en la línea just abans de </aplication>:

        <service
            android:name=".MyFirebaseInstanceIdService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>
        <service
            android:name=".MyFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>

3. Classes a crear i modificar[modifica]

Per tal de què puguem crear l'aplicació i testejar-la serà necessari la creació d'una sèrie de classes les quals les utilitzarem per el registre del token i, per poder observar la comunicació entre el servidor i la nostra aplicació (en aquest cas client). En aquest apartat anirem classe per classe comentant quina és la seva funcionalitat i què ens aporta a la nostra aplicació de prova.

Abans de començar has de tenir en compte que aquestes classes poden tenir biblioteques no incloses al teu projecte. Per tal de que estiguin incloses, simplement hauràs de prémer la combinació Alt + Enter per tal de que l'IDE les inclogui.

MainActivity.java[modifica]

Aquesta classe ens ve creada per defecte quan creem el projecte amb Android Studio. Aquesta classe haurem de modificar el contingut per tal de que quedi de la següent forma:

public class MainActivity extends Activity {
    private BroadcastReceiver broadcastReceiver;
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textViewToken);
        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                textView.setText(SharedPrefManager.getInstance(MainActivity.this).getToken());
            }
        };
        if(SharedPrefManager.getInstance(this).getToken() != null){
            textView.setText(SharedPrefManager.getInstance(MainActivity.this).getToken());
            Log.d("myfcmtoken: ", SharedPrefManager.getInstance(this).getToken());
        }
        registerReceiver(broadcastReceiver,new IntentFilter(MyFirebaseInstanceIdService.TOKEN_BROADCAST));
    }
}

En aquest MainActivity el que farem es gestionar el token registrat en Firebase i mostrar-ho per pantalla. El problema d'això és que el token pot ser registrat més tard del que esperem, per això haurem d'establir una función OnReceive per tal de que quan aquest token ha sigut registrat ho mostrem per pantalla (i també pel log d'Android Studio). Per tal de separar reponsabilitats, aquest enregistrament del token el mourem a una altra classe.

SharedPrefManager.java[modifica]

Aquesta classe serà l'encarregada de l'enregistrament d'aquest per tal de guardar-ho i un mètode per obtenir el token guardat.

public class SharedPrefManager {
    private static final String SHARED_PREF_NAME = "fcmsharedprefdemo";
    private static final String KEY_ACCESS_TOKEN = "token";
    private static Context mCtx;
    private static SharedPrefManager mInstance;
    private SharedPrefManager(Context context){
        mCtx = context;
    }
    public static synchronized SharedPrefManager getInstance(Context context){
        if(mInstance == null){
            mInstance = new SharedPrefManager(context);
        }
        return mInstance;
    }
    public boolean storeToken(String token){
        SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(KEY_ACCESS_TOKEN,token);
        editor.apply();
        return true;
    }
    public String getToken (){
        SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
        return sharedPreferences.getString(KEY_ACCESS_TOKEN, null);
    }
}

MyFirebaseInstanceIdService.java[modifica]

Aquesta classe serà l'encarregada que, una vegada generem el token l'enviem a MainActivity.java per ensenyar-ho per pantalla (per broadcast) i, el guardem amb la classe SharedPrefManager.java

public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {
    public static final String TOKEN_BROADCAST = "myfcmbroadcast";
    @Override
    public void onTokenRefresh() {
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d("myfirebaseid", "Refreshed token: " + refreshedToken);
        getApplicationContext().sendBroadcast(new Intent(TOKEN_BROADCAST));
        storeToken(refreshedToken);
    }
    private void storeToken(String token){
        SharedPrefManager.getInstance(getApplicationContext()).storeToken(token);
    }
}

MyFirebaseMessagingService.java[modifica]

La classe, com el seu propi nom indica, serà qui tindrà el control dels missatges rebuts del servidor. Com veurem a posteriori, aquests missatges els mostrarem al Log d'Android Studio per tal de demostrar que els missatges es reben i es poden observar.

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "fcmexamplemessage";
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d(TAG, "From: " + remoteMessage);
        Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
    }
}

Una vegada s'han implementat totes les classes aquesta hauria de ser la nostra estructura final de classes de la nostra aplicació:

Estructura de classes a Android Studio

4. Proves[modifica]

Primer de tot serà necessari executar l'emulador amb l'aplicació. Per tal d'executar-ho haurem de seleccionar la següent opció i escollir el nostre emulador:

Opció per executar l'aplicació

Una vegada executi la aplicació veurem la següent finestra (el token variarà):

Emulador

Com que nosaltres no tenim cap servidor implementat, ens anirem a la consola de Firebase i seleccionarem el nostre projecte entrant amb el gmail que hem introduït a Android Studio en afegir Firebase. A més, nosaltres quan escollim el projecte, ens haurem de fixar que el nom del projecte serà el mateix nom que el projecte d'Android Studio.

Per fer la prova, ens anirem a la secció Cloud Messaging:

Opcions en la consola de Firebase

Després a Send your first message.

Primer missatge amb Firebase Cloud Messaging

Una vegada ens trobem allà, escriurem el títol del missatge i el contingut del missatge

Enviar un missatge amb Firebase

Si nosaltres volem enviar per token ho hauriem de fer amb el token que mostrem per pantalla a l'aplicació. Ens hauriem de dirigir a l'opció Probar en el dispositiu i especificar el token.

Enviar a dispositiu mitjançant token

Una vegada s'ha omplert el camp del missatge a enviar i anirem a Segmentación. En aquí podrem especificar a qui va dirigit aquest missatge. En el nostre cas simplement especificarem la nostra aplicació i seleccionarem Siguiente

Podem seleccionar a qui enviar el missatge

Una vegada s'hagi escollit a qui enviar, es podrà programar quan enviem el missatge. De fet, tindrem múltiples opcions com programar un dia concret per enviar el missatge però nosaltres per fer la prova farem que es faci al moment.

Programació missatges

I, una vegada s'ha fet tot això, anirem a Publicar per enviar el missatge.

Una vegada aquest missatge és enviat, ens anirem a Android Studio i a Logcat per veure com el missatge és rebut. Filtrem el Log per la paraula "notification" i ho veiem:

Missatge rebut de l'aplicació

Referències[modifica]