web-dev-qa-db-fra.com

Firebase onMessageReceived non appelé lorsque l'application est en arrière-plan

J'utilise Firebase pour notre service de messagerie dans notre Android. J'ai beaucoup étudié Firebase et je comprends que si l'application s'exécute au premier plan ou maintenant va changer la type de données reçues dans la méthode onMessageReceived .

Ce que j'essaie d'accomplir, c'est d'analyser les données entrantes du Remotemessage et de faire quelque chose de différent en fonction de la balise personnalisée. IE, si le mappage de données contient un champ appelé "My_Custom_Tag", je veux remplacer complètement le message Firebase standard qui apparaît et en écrire un personnalisé.

Le problème est que, lorsque l'application s'exécute en arrière-plan, tout code que je mets dans le onMessageReceived jamais n'est déclenché. Cela fonctionne très bien lorsque l'application s'exécute au premier plan, mais ne détectera/ne recevra rien si l'application est en arrière-plan.

Voici un exemple de code ci-dessous:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);

    Map<String, String> aMap = remoteMessage.getData();
    //Custom object here for easier parsing
    PushNotificationsPojo pojo = this.convertResponseToPojo(aMap);

    if(pojo == null){
        passToFirebase(remoteMessage);
        return;
    }

    if(pojo.getData().getCustomTag().equals(PushNotificationsPojo.ID_TAG_CHAT_MESSAGE)) {
        createCustomNotification1(pojo);

    } else if (pojo.getData().getCustomTag().equals(PushNotificationsPojo.ID_TAG_SOME_OTHER_MESSAGE)){
        createCustomNotification2(pojo);

    } else if (pojo.getData().getCustomTag().equals(PushNotificationsPojo.ID_TAG_STUFF_AND_WHATNOT)) {
        createCustomNotification3(pojo);

    } else {
        passToFirebase(remoteMessage);
    }
}

Ma question est de savoir comment modifier MyFirebaseMessagingService pour pouvoir vérifier les données entrantes, déterminer les informations de balise et décider de les transmettre à Firebase pour qu'il puisse utiliser la gestion standard ou de ne pas les transmettre à Firebase et d'écrire mon propre notification d'affichage personnalisée pendant que mon application s'exécute en arrière-plan?

Merci a tous!

PS, y a-t-il une chance que le Firebase-Dungeon-Master Frank van Puffelen ait une pensée?

9
Silmarilos

Supprimez la charge utile de notification de vos messages FCM afin que la charge utile de données soit livrée à la méthode onMessageReceived.

Lisez attentivement ceci et ceci .

Lorsque votre application est en arrière-plan, la charge utile de données est transmise à la méthode onMessageReceived uniquement s'il n'y a pas de charge utile de notification . ( Marquez les mots )

Dans le cas où les deux charges utiles existent, le système gère automatiquement la partie de notification (barre d'état système) et votre application obtient la charge utile de données dans les extras de l'intention de l'activité du lanceur (après que l'utilisateur a tapé sur la notification).

Afin de pouvoir servir les deux plates-formes avec succès, Android et iOS, vous devrez peut-être envoyer des messages FCM différents selon le système d'exploitation du client.

30
kws

Écoutez attentivement, j'ai parcouru de nombreux liens et j'ai finalement trouvé une solution ici.

  1. Lorsque l'application est en arrière-plan, la méthode onMessageReceived doit appeler

Cette charge utile fonctionnera ...

{
  "data":{
    "title": "hello",
    "body": "this is body"
  },
  "to": "c5iuJ7iDnoc:APA91bG6j2c5tiQ3rVR9tBdrCTfDQYxkPwLuNFWzRuGHrBpWiOajR-DKef9EZEEVKA-kUBfXVcqHT-mClYfad06R_rBjhRZFKVdBL7_joXE5hFEwR45Qk8wgQdia2b-LmjI1IheFGZS8"
}

Cette charge utile ne fonctionnera pas ...

{
  "notification":{
    "title": "hello",
    "body": "this is body"
  },
  "to": "c5iuJ7iDnoc:APA91bG6j2c5tiQ3rVR9tBdrCTfDQYxkPwLuNFWzRuGHrBpWiOajR-DKef9EZEEVKA-kUBfXVcqHT-mClYfad06R_rBjhRZFKVdBL7_joXE5hFEwR45Qk8wgQdia2b-LmjI1IheFGZS8"
}

Parce que lorsque la charge contient "notification" onMessageReceived n'appellera pas

5
sssvrock

Dans ce post , la réponse Koot pourrait être votre solution. Il a dit: "J'ai eu le même problème. Il est plus facile d'utiliser le" message de données "au lieu de la" notification ". Le message de données charge toujours la classe onMessageReceived."

ma solution est selon ses conseils

{
  "condition": "'reader' in topics",

  "data": {
    "title":"Please Check",
    "message": "This is a Firebase Cloud Messaging Topic Message 5!"
   }
}
2
Ko Nyan

À peu près sûr, vous connaissez déjà le comportement dans Android que lorsque vous utilisez à la fois la charge utile notification et data, le système Android attrape ce qui est dans le notification et le data la charge utile est incluse dans l'intention quand il est tapé.

AFAIK, c'est la seule façon de procéder (comme mentionné par @ArthurThompson ici ) et si vous voulez vraiment vous assurer que onMessageReceived() est toujours appelé, vous devez seulement use data payload (comme mentionné par @DiegoGiorgini ici ) Cependant, j'ai regardé autour, peut-être qu'il y a une autre façon.

Je ne l'ai pas essayé moi-même, mais avez-vous envisagé en vérifiant quelles notifications sont dans la barre d'état , alors si votre notification existe (, vous ne savez pas vraiment si vous pouvez identifiez en fait celle qui est une notification pour votre application ), appelez les méthodes que vous appelez habituellement dans onMessageReceived().

Une approche que vous pouvez également faire consiste à détecter si le ou les appareils auxquels vous allez envoyer le message est un appareil Android sur votre serveur d'applications, puis envoyer uniquement un data charge utile.

1
AL.