Saltar al contenido

Firebase Cloud Messaging: manejo del cierre de sesión

Solución:

Bueno. Así que logré hacer algunas pruebas y concluí lo siguiente:

  1. deleteToken() es la contraparte de getToken(String, String), pero no para getToken().

Solo funciona si la ID de remitente que está pasando es una ID de remitente diferente (no la misma ID que se puede ver en su google-services.json). Por ejemplo, si desea permitir que un servidor diferente envíe a su aplicación, llame getToken("THEIR_SENDER_ID", "FCM") para darles autorización para enviar a su aplicación. Esto devolverá un token de registro diferente que corresponde solo a ese remitente específico.

En el futuro, si decide eliminar su autorización para enviarlo a su aplicación, deberá utilizar deleteToken("THEIR_SENDER_ID", "FCM"). Esto invalidará el token correspondiente, y cuando el Remitente intente enviar un mensaje, como el comportamiento previsto, recibirá un NotRegistered error.

  1. Para eliminar el token de su propio remitente, el manejo correcto es usar deleteInstanceId().

Mención especial esta respuesta de @Prince, específicamente el ejemplo de código para ayudarme con esto.

Como ya hace @ MichałK en su publicación, después de llamar al deleteInstanceId(), getToken() debe llamarse para enviar una solicitud de un nuevo token. Sin embargo, no tiene que llamarlo la segunda vez. Siempre y cuando onTokenRefresh() onNewToken() está implementado, debería activarse automáticamente proporcionándole el nuevo token.

Para abreviar, deleteInstanceId() > getToken() > comprobar onTokenRefresh() onNewToken().

Nota: Llamando deleteInstanceId() no solo eliminará el token de su propia aplicación. Eliminará todas las suscripciones a temas y todos los demás tokens asociados con la instancia de la aplicación.


¿Estás seguro de que estás llamando? deleteToken() ¿adecuadamente? El valor para la audiencia debe ser (también visto en mi respuesta que vinculó) es “establecido en el ID de remitente del servidor de aplicaciones”. Estas pasando el getId() valor que no es el mismo que el ID del remitente (contiene el valor del ID de la instancia de la aplicación). Además, ¿cómo envía el mensaje (servidor de aplicaciones o consola de notificaciones)?

getToken() y getToken(String, String) devuelve diferentes tokens. Vea mi respuesta aquí.

Yo tambien probé FirebaseInstanceId.getInstance().deleteInstanceId(), pero luego la próxima vez que llame FirebaseInstanceId.getInstance.getToken Recibo nulo (funciona en el segundo intento).

Probablemente sea porque la primera vez que llamas al getToken(), todavía se está generando. Es solo el comportamiento previsto.

Supongo que despues deleteInstanceId Podría llamar de inmediato getToken() de nuevo, pero parece un truco.

Realmente no. Así es como obtendrá el nuevo token generado (siempre que ya esté generado). Entonces creo que está bien.

Hice una breve investigación sobre cuál sería la solución más elegante para recuperar el control total (suscribirse y cancelar la suscripción a FCM) como antes. Habilite y deshabilite el FCM después de que el usuario inicie o cierre sesión.

Paso 1. – Evitar la inicialización automática

Firebase ahora maneja el InstanceID y todo lo demás que necesite generar un token de registro. Primero que nada necesitas prevenir inicialización automática. Según la documentación de configuración oficial, debe agregar estos metadatos valores a tu AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<application>

  <!-- FCM: Disable auto-init -->
  <meta-data android:name="firebase_messaging_auto_init_enabled"
             android:value="false" />
  <meta-data android:name="firebase_analytics_collection_enabled"
             android:value="false" />

  <!-- FCM: Receive token and messages -->
  <service android:name=".FCMService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
  </service>

</application>

Ahora desactivó el proceso automático de solicitud de token. Al mismo tiempo, tiene la opción de habilitarlo nuevamente en tiempo de ejecución por código.

Paso 2. – Implementar enableFCM() y disableFCM() funciones

Si habilita la inicialización automática nuevamente, recibió un nuevo token de inmediato, por lo que esta es una manera perfecta de implementar el enableFCM() método. Toda la información de suscripción asignada a InstanceID, por lo que cuando la elimine, inicie la cancelación de la suscripción de todos los temas. De esta manera podrá implementar disableFCM() método, simplemente desactive el inicio automático antes de eliminarlo.

public class FCMHandler {

    public void enableFCM(){
        // Enable FCM via enable Auto-init service which generate new token and receive in FCMService
        FirebaseMessaging.getInstance().setAutoInitEnabled(true);
    }

    public void disableFCM(){
        // Disable auto init
        FirebaseMessaging.getInstance().setAutoInitEnabled(false);
        new Thread(() -> {
            try {
                // Remove InstanceID initiate to unsubscribe all topic
                // TODO: May be a better way to use FirebaseMessaging.getInstance().unsubscribeFromTopic()
                FirebaseInstanceId.getInstance().deleteInstanceId();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

}

Paso 3. – FCMService implementación: recepción de tokens y mensajes

En el último paso, debe recibir el nuevo token y enviarlo directamente a su servidor. Por otro lado, recibirá su mensaje de datos y simplemente lo hará lo que quiera.

public class FCMService extends FirebaseMessagingService {

    @Override
    public void onNewToken(String token) {
        super.onNewToken(token);
        // TODO: send your new token to the server
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        String from = remoteMessage.getFrom();
        Map data = remoteMessage.getData();
        if (data != null) {
            // TODO: handle your message and data
            sendMessageNotification(message, messageId);
        }
    }

    private void sendMessageNotification(String msg, long messageId) {
        // TODO: show notification using NotificationCompat
    }
}

Creo que esta solución es clara, sencilla y transparente. Probé en un entorno de producción y funciona. Espero que haya sido de ayuda.

Estaba trabajando en el mismo problema, cuando terminé mi logout() de mi aplicación. Pero el problema fue que después de cerrar la sesión, todavía recibía notificaciones automáticas de Firebase. lo intenté eliminar el token de Firebase. Pero después de eliminar el token en mi logout() método, es null cuando lo consulto en mi login() método. Después de trabajar 2 días finalmente obtuve una solución.

  1. En tus logout() método, elimine el token de Firebase en segundo plano porque no puede eliminar el token de Firebase del hilo principal

    new AsyncTask<Void,Void,Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try
            {
                FirebaseInstanceId.getInstance().deleteInstanceId();
            } catch (IOException e)
            {
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        protected void onPostExecute(Void result) {
            // Call your Activity where you want to land after log out
        }
    }.execute();
    
  2. En tus login() , vuelva a generar el token de Firebase.

    new AsyncTask<Void,Void,Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            String token = FirebaseInstanceId.getInstance().getToken();
            // Used to get firebase token until its null so it will save you from null pointer exeption
            while(token == null) {
                token = FirebaseInstanceId.getInstance().getToken();
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
        }
    }.execute();
    
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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