Comment gérer la notification lorsque l'application en arrière-plan dans Firebase

429

Voici mon manifeste

    <service android:name=".fcm.PshycoFirebaseMessagingServices">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <service android:name=".fcm.PshycoFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

Lorsque l'application est en arrière-plan et qu'une notification arrive, la notification par défaut arrive et n'exécute pas mon code de onMessageReceived.

Voici mon onMessageReceivedcode. Ceci est invoqué si mon application s'exécute au premier plan, pas lorsqu'elle est en arrière-plan. Comment exécuter ce code lorsque l'application est également en arrière-plan?

// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // If the application is in the foreground handle both data and notification messages here.
    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
    data = remoteMessage.getData();
    String title = remoteMessage.getNotification().getTitle();
    String message = remoteMessage.getNotification().getBody();
    String imageUrl = (String) data.get("image");
    String action = (String) data.get("action");
    Log.i(TAG, "onMessageReceived: title : "+title);
    Log.i(TAG, "onMessageReceived: message : "+message);
    Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
    Log.i(TAG, "onMessageReceived: action : "+action);

    if (imageUrl == null) {
        sendNotification(title,message,action);
    } else {
        new BigPictureNotification(this,title,message,imageUrl,action);
    }
}
// [END receive_message]
Parth Patel
la source
1
Il est écrit dans l' exemple de remplacement de onMessageReceived () , dit la deuxième ligne de commentaire Not getting messages here? See why this may be: goo.gl/39bRNJ . La solution, comme les réponses ci-dessous, peut être trouvée dans la documentation dans Messages avec notification et données utiles
fllo
En bref, pour réveiller votre application supprimée, vous devez toujours envoyer une notification avec un objet de données pour appeler votre gestionnaire de classe de service de notification FirebaseMessagingService.onMessageReceived () dans votre application. Essayez également de l'envoyer non pas à partir de la console Firebase, mais pour le publier ailleurs (par exemple, service de test en ligne).
Zon
1
cette solution a fonctionné pour moi stackoverflow.com/a/44150822/6632278 j'espère que cela aide. Bonne chance
Tony Barajas
ce que ".fcm." PshycoFirebaseMessagingServices est dans votre manifeste? Je reçois une erreur de classe non trouvée ... et je n'ai trouvé nulle part quelle est cette première partie du paramètre.
Éder Rocha Bezerra

Réponses:

661

1. Pourquoi cela se produit-il?

Il existe deux types de messages dans FCM (Firebase Cloud Messaging):

  1. Afficher les messages : ces messages déclenchent le onMessageReceived()rappel uniquement lorsque votre application est au premier plan
  2. Messages de données : ces messages déclenchent le onMessageReceived()rappel même si votre application est au premier plan / en arrière-plan / supprimée

REMARQUE: L' équipe Firebase n'a pas encore développé d'interface utilisateur à envoyer data-messagesà vos appareils. Vous devez utiliser votre serveur pour envoyer ce type!



2. Comment?

Pour ce faire, vous devez effectuer une POSTdemande à l'URL suivante:

POST https://fcm.googleapis.com/fcm/send

En-têtes

  • Légende: Content-Type , Valeur: application/json
  • Légende: Authorization , Valeur: key=<your-server-key>

Corps utilisant des sujets

{
    "to": "/topics/my_topic",
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     }
}

Ou si vous souhaitez l'envoyer vers des appareils spécifiques

{
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     },
    "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}


REMARQUE: assurez-vous que vous n'ajoutez pas de clé JSON notification
REMARQUE: pour obtenir votre clé de serveur, vous pouvez la trouver dans la console Firebase:Your project -> settings -> Project settings -> Cloud messaging -> Server Key

3. Comment gérer le message de notification push?

Voici comment vous gérez le message reçu:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String myCustomKey = data.get("my_custom_key");

     // Manage data
}
Antonio
la source
4
Vous pouvez envoyer des clés de «données» et de «notification» dans la même notification en suivant ces étapes stackoverflow.com/a/42279260/2734021 :)
Daniel S.
15
Firebase team have not developed a UI to send data-messages to your devices, yet.Cela a-t-il changé au cours de la dernière année?
Hankrecords
2
@Antonio In oreo lorsque l'application est supprimée, onMessageReceived n'est pas appelé. J'ai juste une charge utile avec des données uniquement. avez-vous une mise à jour?
Samir Mangroliya
63
Lorsque l'application est en arrière onMessageReceived- plan, elle n'est pas appelée et c'est un problème grave dans FCM !!! Veuillez également mettre à jour votre réponse.
Muhammad Babar
2
Eh bien, pour moi, il semble que cela se produise sur certains appareils Android. J'ai passé des heures à penser que c'était un problème réel, mais il s'est avéré que ce n'était rien. Donc, mon conseil est de le tester sur différents appareils. Je l'ai même testé sur une machine virtuelle et j'ai reçu la notification même lorsque l'application a été tuée. Je dis juste cela pour gagner du temps à quelqu'un.
Tarek-Dev du
158

Pour créer une bibliothèque Firebase pour appeler votre onMessageReceived () dans les cas suivants

  1. Application en premier plan
  2. App en arrière-plan
  3. L'application a été tuée

vous ne devez pas mettre la «notification» de la clé JSON dans votre demande à l'API Firebase mais utiliser à la place les «données», voir ci-dessous.

Le message suivant n'appellera pas votre onMessageReceived () lorsque votre application est en arrière-plan ou supprimée , et vous ne pouvez pas personnaliser votre notification.

{
   "to": "/topics/journal",
   "notification": {
   "title" : "title",
   "text": "data!",
   "icon": "ic_notification"
    }
}

mais à la place, cela fonctionnera

{
  "to": "/topics/dev_journal",
   "data": {
       "text":"text",
       "title":"",
       "line1":"Journal",
       "line2":"刊物"
   }
} 

Fondamentalement, le message est envoyé dans l'argument RemoteMessage avec votre objet de données en tant que carte, puis vous pouvez gérer la notification dans onMessageReceived comme dans l'extrait ici

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();

     //you can get your text message here.
     String text= data.get("text");


     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        // optional, this is to make beautiful icon
             .setLargeIcon(BitmapFactory.decodeResource(
                                    getResources(), R.mipmap.ic_launcher))  
        .setSmallIcon(smallIcon)  //mandatory
      .......
    /*You can read more on notification here:
    https://developer.android.com/training/notify-user/build-notification.html
    https://www.youtube.com/watch?v=-iog_fmm6mE
    */
}
Teerakiat Chitawattanarat
la source
1
Est-il possible d'y parvenir à partir de la console Firebase?
koder
@koder, malheureusement, la console Firebase ne prend pas en charge cela, vous devez utiliser un outil pour envoyer une demande de message à Firebase tel que curl ou postman (plugin chrome), API de messagerie Firebase, veuillez vous référer au document ici - firebase.google.com/docs / cloud-messaging / http-server-ref
Teerakiat Chitawattanarat
1
c'est ce que je cherchais depuis plus d'une journée ..... Merci beaucoup ça a parfaitement fonctionné. et il serait préférable que vous expliquiez comment les paires de valeurs clés dans les données peuvent être traitées dans onMessageReceived () pour démarrer une activité avec ces valeurs.
Boopathi T
25
Votre méthode fonctionne bien lorsque l'application est en arrière-plan, mais lorsque l'application est supprimée, je ne reçois pas de données
Sanzhar
8
Même problème de Sanzhar. Si l'application est tuée, je ne reçois aucun message.
Giacomo M
104

J'ai l'impression que toutes les réponses sont incomplètes, mais toutes ont quelque chose dont vous avez besoin pour traiter une notification contenant des données lorsque votre application est en arrière-plan.

Suivez ces étapes et vous pourrez traiter vos notifications lorsque votre application est en arrière-plan.

1.Ajoutez un filtre d'intention comme celui-ci:

<activity android:name=".MainActivity">
      <intent-filter>
           <action android:name=".MainActivity" />
           <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
</activity>

à une activité dont vous souhaitez traiter les données de notification.

  1. Envoyez des notifications au format suivant:

    { 
     "notification" : {
            "click_action" : ".MainActivity", 
            "body" : "new Symulti update !", 
            "title" : "new Symulti update !", 
            "icon" : "ic_notif_symulti" }, 
     "data": { ... },
     "to" : "c9Vaa3ReGdk:APA91bH-AuXgg3lDN2WMcBrNhJZoFtYF9" }

La clé ici est d'ajouter

"click_action" : ".MainActivity"

où .MainActivity est l'activité avec le filtre d'intention que vous avez ajouté à l'étape 1.

  1. Obtenez des informations sur les "données" à partir de la notification dans le onCreate de ".MainActivity":

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //get notification data info
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
           //bundle must contain all info sent in "data" field of the notification
        }
    }

Et cela devrait être tout ce que vous devez faire. J'espère que cela aide quelqu'un :)

Daniel S.
la source
5
Ce devrait être la bonne réponse. Aucun des documents ne dit quoi que ce soit d'exiger une action click_action ET un filtre d'intention pour que la notification apparaisse même dans la barre d'état. Ils sont tous les deux requis.
airowe
@airowe, il n'est pas nécessaire que la notification apparaisse
AlwaysConfused
J'ai à la fois des blocs de données et de notification mais je ne peux pas recevoir de données en activité?
Ashwani
3
Je ne comprends tout simplement pas que ce n'est pas la réponse acceptée. Sans click_action, cela ne fonctionnera tout simplement pas. J'ai sauvé ma journée
Arun Shankar
4
Merci pour votre soutien @ArunShankar. La réponse acceptée a été répondue 7 mois avant la mienne et c'est une bonne réponse. Je ne comprends pas pourquoi personne ne parle de click_action et c'est pourquoi j'ai ajouté ma réponse. Je suis très heureux que cela soit très utile pour beaucoup de gens et c'est ce qui compte à la fin de la journée :)
Daniel S.
42

Selon la documentation de Firebase dans l' envoi en aval à l'aide de Firebase , il existe 2 types de charge utile:

  1. Les données

    Ce paramètre spécifie les paires clé-valeur personnalisées de la charge utile du message. L'application client est responsable du traitement des messages de données. Les messages de données n'ont que des paires clé-valeur personnalisées.

  2. notification

    Ce paramètre spécifie les paires clé-valeur prédéfinies visibles par l'utilisateur de la charge utile de notification. FCM affiche automatiquement le message sur les appareils des utilisateurs finaux au nom de l'application cliente. Les messages de notification ont un ensemble prédéfini de clés visibles par l'utilisateur.

Lorsque vous êtes au premier plan, vous pouvez obtenir les données dans FCM en utilisant onMessageReceived () , vous pouvez obtenir vos données à partir de la charge utile des données .

data = remoteMessage.getData();
String customData = (String) data.get("customData");

Lorsque vous êtes en arrière-plan, FCM affichera une notification dans la barre d'état système en fonction des informations de la charge utile de notification . Le titre, le message et l'icône utilisés pour la notification dans la barre d'état système proviennent de la charge utile de notification .

{
  "notification": {
        "title" : "title",
        "body"  : "body text",
        "icon"  : "ic_notification",
        "click_action" : "OPEN_ACTIVITY_1"
       }
}

Cette charge utile de notification est utilisée lorsque vous souhaitez afficher automatiquement une notification sur la barre d'état système lorsque votre application est en arrière-plan. Pour obtenir des données de notification lorsque votre application en arrière-plan, vous devez ajouter click_action dans la charge utile de notification .

Si vous souhaitez ouvrir votre application et effectuer une action spécifique [en arrière-plan], définissez click_action dans la charge utile de notification et mappez-la à un filtre d'intention dans l'activité que vous souhaitez lancer. Par exemple, définissez click_action sur OPEN_ACTIVITY_1 pour déclencher un filtre d'intention comme celui-ci:

<intent-filter>
  <action android:name="OPEN_ACTIVITY_1" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Mettez ce filtre d'intention sur votre manifeste, dans l'une de vos balises d'activité. Lorsque vous cliquez sur la notification, elle ouvre l'application et passe directement à l'activité que vous définissez dans click_action, dans ce cas "OPEN_ACTIVTY_1". Et à l'intérieur de cette activité, vous pouvez obtenir les données en:

Bundle b = getIntent().getExtras();
String someData = b.getString("someData");

J'utilise FCM pour mon application Android et j'utilise les deux charges utiles. Voici l'exemple JSON que j'utilise:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification",
    "click_action" : "OPEN_ACTIVITY_1"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}
Hendy Evan
la source
"Mettez ce filtre d'intention sur votre manifeste, à l'intérieur de la balise d'application." vous ne pouvez pas mettre de filtre d'intention à l'intérieur de la balise d'application.
Kyrylo Zapylaiev
votre JSON ne montre pas où va la clé click_action.
Josh
ce n'est pas la bonne réponse? qu'est-ce que l'action clic n où va-t-elle? quelqu'un devrait voter contre ou nettoyer cela
rana
1
@KyryloZapylaiev Je viens de corriger et de mettre à jour la réponse: "Mettez ce filtre d'intention sur votre manifeste, à l'intérieur d'une de vos balises d'activité".
Dika
1
@Josh mis à jour et formaté. vous pouvez le vérifier à nouveau
Dika
32

Selon les documents

Gérer les messages dans une application en arrière-plan

Lorsque votre application est en arrière-plan, Android dirige les messages de notification vers la barre d'état système. Un utilisateur tapant sur la notification ouvre le lanceur d'applications par défaut.

Cela inclut les messages qui contiennent à la fois des notifications et des données utiles. Dans ces cas, la notification est envoyée dans la barre d'état système de l'appareil et la charge utile des données est livrée dans les extras de l'intention de votre activité de lancement.

Si vous souhaitez ouvrir votre application et effectuer une action spécifique, définissez click_action dans la charge utile de notification et mappez-la à un filtre d'intention dans l'activité que vous souhaitez lancer. Par exemple, définissez click_action sur OPEN_ACTIVITY_1 pour déclencher un filtre d'intention comme celui-ci:

 <intent-filter>   <action android:name="OPEN_ACTIVITY_1" />  
 <category android:name="android.intent.category.DEFAULT" />
 </intent-filter>

Éditer :

Sur la base de ce fil :

Vous ne pouvez pas définir la charge utile click_action à l'aide de la console Firebase. Vous pouvez essayer de tester avec une commande curl ou un serveur http personnalisé

curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>" 
     --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  
     -d "{\"to\":\"/topics/news\",\"notification\": 
         {\"title\": \"Click Action Message\",\"text\": \"Sample message\",
            \"click_action\":\"OPEN_ACTIVITY_1\"}}"
Shubhank
la source
1
tu as raison. j'ai lu les documents. mais je ne sais pas où mettre cela dans mon manifeste? je dois exécuter le code sur le onMessageReceived sur ce fichier java donc pour cela que dois-je faire monsieur?
Parth Patel
Vous ne pouvez pas faire en sorte que l'application appelle automatiquement onMessageReveiced lorsqu'elle est en arrière-plan. Au lieu de cela, vous devez gérer l'intention reçue et faire en sorte que le gestionnaire l'appelle. Ou probablement, il est préférable d'implémenter une classe / méthode distincte qui est appelée à la fois par onMessageReveiced et votre gestion d'intention. J'ai ajouté un gestionnaire à onNewIntent de l'activité principale et cela fonctionne bien pour moi.
diidu
trop tard pour répondre aux questions de @Parath Patel mais peut-être que cela aidera quelqu'un d'autre avec les mêmes problèmes, jetez un œil à ma réponse ici stackoverflow.com/a/42279260/2734021
Daniel S.
où devait mettre cette action? pour mon activité ou service Firebasemessage?
Mahdi
** sur plusieurs redirection de notification ne fonctionne pas? par exemple: si j'ai trois notifications de fcm en arrière-plan en utilisant "click_action", la première notification a été redirigée avec succès, puis 2 notifications, cliquez sur la redirection d'activité ne fonctionne pas
prasanthMurugan
24

Fonctionne depuis juillet 2019

Android compileSdkVersion 28, buildToolsVersion 28.0.3 et messagerie Firebase: 19.0.1

Après de nombreuses heures de recherche à travers toutes les autres questions et réponses de StackOverflow, et en essayant d'innombrables solutions obsolètes, cette solution a réussi à afficher des notifications dans ces 3 scénarios:

- L'application est au premier plan:
la notification est reçue par la méthode onMessageReceived dans ma classe MyFirebaseMessagingService

- L'application a été supprimée (elle ne fonctionne pas en arrière-plan): la notification est envoyée automatiquement au bac de notification par FCM. Lorsque l'utilisateur touche la notification, l'application est lancée en appelant l'activité qui a android.intent.category.LAUNCHER dans le manifeste. Vous pouvez obtenir la partie données de la notification en utilisant getIntent (). GetExtras () à la méthode onCreate ().

- L'application est en arrière-plan: la notification est envoyée automatiquement au bac de notification par FCM. Lorsque l'utilisateur touche la notification, l'application est mise au premier plan en lançant l'activité qui a android.intent.category.LAUNCHER dans le manifeste. Comme mon application a launchMode = "singleTop" dans cette activité, la méthode onCreate () n'est pas appelée car une activité de la même classe est déjà créée, à la place la méthode onNewIntent () de cette classe est appelée et vous obtenez la partie données de la notification là-bas en utilisant intent.getExtras ().

Étapes: 1- Si vous définissez l'activité principale de votre application comme ceci:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:screenOrientation="portrait"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name=".MainActivity" />
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

2- Ajoutez ces lignes à la méthode onCreate () de votre classe MainActivity.class

Intent i = getIntent();
Bundle extras = i.getExtras();
if (extras != null) {
    for (String key : extras.keySet()) {
        Object value = extras.get(key);
        Log.d(Application.APPTAG, "Extras received at onCreate:  Key: " + key + " Value: " + value);
    }
    String title = extras.getString("title");
    String message = extras.getString("body");
    if (message!=null && message.length()>0) {
        getIntent().removeExtra("body");
        showNotificationInADialog(title, message);
    }
}

et ces méthodes à la même classe MainActivity.class:

@Override
public void onNewIntent(Intent intent){
    //called when a new intent for this class is created.
    // The main case is when the app was in background, a notification arrives to the tray, and the user touches the notification

    super.onNewIntent(intent);

    Log.d(Application.APPTAG, "onNewIntent - starting");
    Bundle extras = intent.getExtras();
    if (extras != null) {
        for (String key : extras.keySet()) {
            Object value = extras.get(key);
            Log.d(Application.APPTAG, "Extras received at onNewIntent:  Key: " + key + " Value: " + value);
        }
        String title = extras.getString("title");
        String message = extras.getString("body");
        if (message!=null && message.length()>0) {
            getIntent().removeExtra("body");
            showNotificationInADialog(title, message);
        }
    }
}


private void showNotificationInADialog(String title, String message) {

    // show a dialog with the provided title and message
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();
}

3- Créez la classe MyFirebase comme ceci:

package com.yourcompany.app;

import android.content.Intent;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {


    public MyFirebaseMessagingService() {
        super();
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        Log.d(Application.APPTAG, "myFirebaseMessagingService - onMessageReceived - message: " + remoteMessage);

        Intent dialogIntent = new Intent(this, NotificationActivity.class);
        dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        dialogIntent.putExtra("msg", remoteMessage);
        startActivity(dialogIntent);

    }

}

4- Créez une nouvelle classe NotificationActivity.class comme ceci:

package com.yourcompany.app;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper;

import com.google.firebase.messaging.RemoteMessage;

public class NotificationActivity extends AppCompatActivity {

private Activity context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    Bundle extras = getIntent().getExtras();

    Log.d(Application.APPTAG, "NotificationActivity - onCreate - extras: " + extras);

    if (extras == null) {
        context.finish();
        return;
    }

    RemoteMessage msg = (RemoteMessage) extras.get("msg");

    if (msg == null) {
        context.finish();
        return;
    }

    RemoteMessage.Notification notification = msg.getNotification();

    if (notification == null) {
        context.finish();
        return;
    }

    String dialogMessage;
    try {
        dialogMessage = notification.getBody();
    } catch (Exception e){
        context.finish();
        return;
    }
    String dialogTitle = notification.getTitle();
    if (dialogTitle == null || dialogTitle.length() == 0) {
        dialogTitle = "";
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(context, R.style.myDialog));
    builder.setTitle(dialogTitle);
    builder.setMessage(dialogMessage);
    builder.setPositiveButton(getResources().getString(R.string.accept), new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();

}

}

5- Ajoutez ces lignes à votre manifeste d'application, à l'intérieur de vos tags

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

    <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/>

    <activity android:name=".NotificationActivity"
        android:theme="@style/myDialog"> </activity>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/notification_icon"/>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/color_accent" />

6- Ajoutez ces lignes dans votre méthode Application.java onCreate (), ou dans la méthode MainActivity.class onCreate ():

      // notifications channel creation
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      // Create channel to show notifications.
      String channelId = getResources().getString("default_channel_id");
      String channelName = getResources().getString("General announcements");
      NotificationManager notificationManager = getSystemService(NotificationManager.class);
      notificationManager.createNotificationChannel(new NotificationChannel(channelId,
              channelName, NotificationManager.IMPORTANCE_LOW));
  }

Terminé.

Maintenant, pour que cela fonctionne correctement dans les 3 scénarios mentionnés, vous devez envoyer la notification à partir de la console Web Firebase de la manière suivante:

Dans la section Notification: Titre de notification = Titre à afficher dans la boîte de dialogue de notification (facultatif) Texte de notification = Message à afficher à l'utilisateur (obligatoire) Puis dans la section Cible: Application = votre application Android et dans la section Options supplémentaires: Canal de notification Android = default_channel_id Clé de données personnalisées: valeur de titre: (même texte ici que dans le champ Titre de la section Notification) clé: valeur de corps: (même texte ici que dans le champ Message de la section Notification) clé: valeur click_action: .MainActivity Sound = Désactivé
expire = 4 semaines

Vous pouvez le déboguer dans l'émulateur avec l'API 28 avec Google Play.

Bon codage!

alvaro
la source
2
Merci pour cette excellente réponse.
Alex Chengalan
@alvaro, Si je veux ouvrir Url lorsque je reçois une notification, comment je peux gérer cela
engmms
ne fonctionne pas in vivo téléphone opp lorsque l'application est proche ou tuée
Développeur Android
Je n'ai pas essayé sur un téléphone Vivo, mais il fonctionne actuellement sur de nombreux autres téléphones Android. Veuillez lire lentement chaque étape, vérifier tous les détails, puis activer les points d'arrêt de débogage à la première ligne de chacune des méthodes que j'ai mentionnées ici, connecter un vrai téléphone à votre ordinateur de développement avec un câble et déboguer l'application lors de l'envoi un message de FCM. Vérifiez que vous envoyez les messages FCM avec tous les paramètres et le format que j'ai mentionnés. Bonne chance!
alvaro
2
Il s'agit de la réponse la plus récente, comme l'indique désormais la documentation Firebase: lorsque votre application est en arrière-plan, Android dirige les messages de notification vers la barre d'état système. Un utilisateur tapant sur la notification ouvre le lanceur d'applications par défaut. Cela inclut les messages qui contiennent à la fois des notifications et des données utiles. Dans ces cas, la notification est envoyée dans la barre d'état système de l'appareil et la charge utile des données est livrée dans les extras de l'intention de votre activité de lancement. ( firebase.google.com/docs/cloud-messaging/android/… ) Tant d'anciennes réponses sont obsolètes
Riot Goes Woof
20

Étant donné que ceux display-messagesqui sont envoyés depuis Firebase Notification UI ne fonctionne que si votre application est au premier plan. Pour data-messages, il est nécessaire de faire un appel POST à FCM

Pas

  1. Installer l'extension Google Chrome Advanced Rest Client entrez la description de l'image ici

  2. Ajoutez les en-têtes suivants

    Clé : Content-Type, valeur : application / json

    Clé : autorisation, valeur : clé = "votre clé de serveur" entrez la description de l'image ici

  3. Ajouter le corps

    • Si vous utilisez des sujets:

      {
          "to" : "/topics/topic_name",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
          }
      }
    • Si vous utilisez l'ID d'enregistrement:

      {
          "registration_ids" : "[{"id"},{id1}]",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
           }
      }

C'est ça!. Écoutez maintenant le onMessageReceivedrappel comme d'habitude.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}
skynet
la source
20

Pour capturer le message en arrière-plan, vous devez utiliser un BroadcastReceiver

import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.legacy.content.WakefulBroadcastReceiver
import com.google.firebase.messaging.RemoteMessage

class FirebaseBroadcastReceiver : WakefulBroadcastReceiver() {

    val TAG: String = FirebaseBroadcastReceiver::class.java.simpleName

    override fun onReceive(context: Context, intent: Intent) {

        val dataBundle = intent.extras
        if (dataBundle != null)
            for (key in dataBundle.keySet()) {
                Log.d(TAG, "dataBundle: " + key + " : " + dataBundle.get(key))
            }
        val remoteMessage = RemoteMessage(dataBundle)
        }
    }

et ajoutez ceci à votre manifeste:

<receiver
      android:name="MY_PACKAGE_NAME.FirebaseBroadcastReceiver"
      android:exported="true"
      android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
</receiver>
Romulano
la source
7
Cela reçoit vraiment le message de notification, lorsque l'application est en arrière-plan. Mais cela n'empêche pas le récepteur Firebase par défaut de le gérer, de sorte que le message s'affiche toujours sous la forme d'une alerte de notification.
Galya
Pour le moment ne fonctionne pas, c'est pourquoi je propose cette solution. Il y a un bug déposé sur la base de bogues Google. Vous voudrez peut-être vérifier cela.
Romulano
Pourriez-vous s'il vous plaît poster un lien vers le bug ici
Galya
comment obtenir des données de notification?
Ravi Vaghela
Cela ne fonctionne clairement pas lorsque l'application est supprimée. J'ai essayé cette solution pendant des heures. pour une raison quelconque, le récepteur fonctionne pendant que l'application est en arrière-plan et ne fonctionne pas lorsque l'application est tuée
XcodeNOOB
16
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}

n'est pas appelé à chaque fois qu'il est appelé uniquement lorsque l'application est en avant-plan

il existe une méthode de remplacement, cette méthode est appelée à chaque fois, quelle que soit l'application qui est au premier plan, en arrière-plan ou supprimée, mais cette méthode est disponible avec cette version api Firebase

c'est la version que vous devez importer de gradle

compile 'com.google.firebase:firebase-messaging:10.2.1'

c'est la méthode

@Override
public void handleIntent(Intent intent) {
    super.handleIntent(intent);

    // you can get ur data here 
    //intent.getExtras().get("your_data_key") 


}

avec l'api firebase précédente, cette méthode n'était pas là, donc dans ce cas, la base de feu se gère quand l'application est en arrière-plan .... maintenant vous avez cette méthode ce que vous voulez faire ... vous pouvez le faire ici dans cette méthode .. ...

si vous utilisez la version précédente, l'activité par défaut commencera dans ce cas, vous pouvez obtenir les données de la même manière

if(getIntent().getExtras() != null && getIntent().getExtras().get("your_data_key") != null) {
String strNotificaiton = getIntent().getExtras().get("your_data_key").toString();

// fais ce que tu veux ....}

généralement c'est la structure du serveur que nous recevons dans la notification

{
    "notification": {
        "body": "Cool offers. Get them before expiring!",
        "title": "Flat 80% discount",
        "icon": "appicon",
        "click_action": "activity name" //optional if required.....
    },
    "data": {
        "product_id": 11,
        "product_details": "details.....",
        "other_info": "......."
    }
}

c'est à u comment vous voulez donner cette clé de données ou vous voulez donner une notification tout ce que vous pouvez donner ....... tout ce que vous donnerez ici avec la même clé u obtiendrez ces données ........ .

il y a peu de cas si vous n'envoyez pas d'action de clic dans ce cas, lorsque vous cliquerez sur la notification, l'activité par défaut s'ouvrira, mais si vous voulez ouvrir votre activité spécifique lorsque l'application est en arrière-plan, vous pouvez appeler votre activité à partir de cette méthode sur handleIntent car cela est appelé à chaque fois

Avinash Jadaun
la source
J'ai mis à jour la messagerie Firebase vers 10.2.1, ajouté des données au message de notification, et cela a fonctionné. Premier plan, arrière-plan et tué. Merci
Firas Shrourou
dans Kotlin, j'obtiens cette erreur: (44, 5) 'handleIntent' dans 'FirebaseMessagingService' est final et ne peut pas être ignoré
ugali soft
Il ne fonctionne pas au-dessus des versions de firebase 11
venu46
14

Selon les documents: 17 mai 2017

Lorsque votre application est en arrière - plan , Android dirige les messages de notification vers la barre d'état système. Un utilisateur tapant sur la notification ouvre le lanceur d'applications par défaut .

Cela inclut les messages qui contiennent à la fois des notifications et des données utiles (et tous les messages envoyés à partir de la console de notifications). Dans ces cas, la notification est envoyée dans la barre d'état système de l'appareil et la charge utile des données est livrée dans les extras de l'intention de votre activité de lancement.

Donc, vous devez utiliser à la fois la notification de charge utile + les données:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

Il n'est pas nécessaire d'utiliser click_action.Vous devez simplement obtenir des exras d'intention sur l' activité LAUNCHER

<activity android:name=".MainActivity">
        <intent-filter>
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>

Le code Java doit être sur la méthode onCreate sur MainActivity:

Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
    Bundle extras = intent.getExtras();
    String someData= extras.getString("someData");
    String someData2 = extras.getString("someData2");
}

Vous pouvez tester à la fois la notification de charge utile + les données de la console de notifications Firebase . N'oubliez pas de remplir des champs de données personnalisés dans la section Options avancées

Mihuilk
la source
14

Voici des concepts plus clairs sur le message Firebase. Je l'ai trouvé auprès de leur équipe d'assistance.

** Firebase a trois types de messages **:

Messages de notification : le message de notification fonctionne en arrière-plan ou au premier plan. Lorsque l'application est en arrière-plan, les messages de notification sont remis dans la barre d'état système. Si l'application est au premier plan, les messages sont traités par onMessageReceived()ou les didReceiveRemoteNotificationrappels. Il s'agit essentiellement de ce que l'on appelle les messages d'affichage.

Messages de données : sur la plateforme Android, les messages de données peuvent fonctionner en arrière-plan et au premier plan. Le message de données sera géré par onMessageReceived (). Une note spécifique à la plate-forme serait ici: Sur Android, la charge utile des données peut être récupérée dans l'intention utilisée pour lancer votre activité. Pour élaborer, si vous en avez "click_action":"launch_Activity_1", vous pouvez récupérer cette intention getIntent()uniquement à partir de Activity_1.

Messages avec notification et données utiles : en arrière-plan, les applications reçoivent la charge utile de notification dans la barre de notification et ne gèrent la charge utile de données que lorsque l'utilisateur appuie sur la notification. Au premier plan, votre application reçoit un objet de message avec les deux charges utiles disponibles. Deuxièmement, le click_actionparamètre est souvent utilisé dans la charge utile de notification et non dans la charge utile de données. S'il est utilisé dans les données utiles, ce paramètre sera traité comme une paire clé-valeur personnalisée et vous devrez donc implémenter une logique personnalisée pour qu'il fonctionne comme prévu.

Aussi, je vous recommande d'utiliser la onMessageReceivedméthode (voir Message de données) pour extraire le bundle de données. D'après votre logique, j'ai vérifié l'objet bundle et je n'ai pas trouvé le contenu de données attendu. Voici une référence à un cas similaire qui pourrait apporter plus de clarté.

Pour plus d'informations, visitez mon ce fil

Md. Sajedul Karim
la source
8

Résumé simple comme celui-ci

  • si votre application est en cours d'exécution;

    onMessageReceived()

est des déclencheurs.

  • si votre application n'est pas en cours d'exécution (supprimée par glissement);

    onMessageReceived()

n'est pas déclenché et livré par direclty. Si vous avez une paire clé-valeur spéciale. Ils ne fonctionnent pas car onMessageReceived () ne fonctionne pas.

J'ai trouvé cette voie;

Dans votre activité de lanceur, mettez cette logique,

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState, R.layout.activity_splash);

    if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("PACKAGE_NAME")) {

        // do what you want

        // and this for killing app if we dont want to start
        android.os.Process.killProcess(android.os.Process.myPid());

    } else {

        //continue to app
    }
}

dans ce bloc if, recherchez vos clés en fonction de l'interface utilisateur de firebase.

Dans cet exemple, ma clé et ma valeur comme ci-dessus; (désolé pour la langue =)) entrez la description de l'image ici

Lorsque mon code fonctionne, j'obtiens "com.rda.note".

android.os.Process.killProcess(android.os.Process.myPid());

avec cette ligne de code, j'ai fermé mon application et ouvert Google Play Market

codage heureux =)

Arda
la source
6

J'ai compris les scénarios,

Lorsque l'application est au premier plan , la méthode onMessageReceived () est appelée à partir de FirebaseService . Ainsi, le pendingIntent défini dans la classe de service sera appelé.

Et lorsque l'application est en arrière - plan , la première activité est appelée.

Maintenant, si vous utilisez une activité splash , vous devez garder à l'esprit que la splashactivity sera appelée, sinon s'il n'y a pas splashActivity, alors quelle que soit la première activité, elle sera appelée.

Ensuite, vous devez vérifier getIntent () de la première activité pour voir s'il contient un ensemble. Si tout va bien, vous verrez que l'ensemble est là avec des valeurs remplies. Si la valeur dans la balise de données envoyée par le serveur ressemble à ceci,

"data": {
    "user_name": "arefin sajib",
    "value": "user name notification"
  }

Ensuite, dans la première activité, vous verrez, il y a une intention valide ( getIntent () n'est pas null ), un bundle valide et un bundle interne, il y aura tout le JSON mentionné ci-dessus avec les données comme clé .

Pour ce scénario, le code d'extraction de valeur ressemblera à ceci,

    if(getIntent()!=null){
            Bundle bundle = getIntent().getExtras();
            if (bundle != null) {
                try {
                   JSONObject object = new JSONObject(bundle.getStringExtra("data"));
String user_name = object.optString("user_name");

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
        }
Shamsul Arefin Sajib
la source
3

Merci à vous tous pour vos réponses. Mais j'ai résolu cela en envoyant un message de données au lieu d'envoyer une notification . Code serveur

<?php
$url = "https://fcm.googleapis.com/fcm/send";
$token = "C-l6T_a7HouUK****";
$serverKey = "AAAAaOcKS00:********";
define( 'API_ACCESS_KEY', $serverKey );
$registrationIds = array($token);
// prep the bundle

$msg = array

(
 'message'  => 'here is a message. message',
 'title'        => 'This is a title. title',
 'subtitle' => 'This is a subtitle. subtitle',
 'tickerText'   => 'Ticker text here...Ticker text here...Ticker text 
 here',
 'vibrate'  => 1,
 'sound'        => 1,
 'largeIcon'    => 'large_icon',
 'smallIcon'    => 'small_icon'

);

$fields = array

(
  'registration_ids'    => $registrationIds,
  'data'            => $msg

);
$headers = array

(
  'Authorization: key=' . API_ACCESS_KEY,
 'Content-Type: application/json'

);


$ch = curl_init();

curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' 
);

curl_setopt( $ch,CURLOPT_POST, true );

curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );

curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );

curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );

curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );

$result = curl_exec($ch );

curl_close( $ch );

echo $result;

?>

Et attrapé les données dans onMessageReceived

public class MyFirebaseMessagingService extends FirebaseMessagingService     {

  private static final String TAG = "MyFirebaseMsgService";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

      sendNotification(remoteMessage.getData().get("message"));
     }
   // Check if message contains a notification payload.
    else if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    sendNotification(remoteMessage.getNotification().getBody());
    }


}
   private void sendNotification(String messageBody) {
    Intent intent = new Intent(this, Notify.class).putExtra("msg",messageBody);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    String channelId = "idddd";
    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(MyFirebaseMessagingService.this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("FCM Message")
                    .setContentText(messageBody)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
Android Sanaullah
la source
1
fonctionne-t-il également avec un arrière-plan?
Tabish khan
@Tabishkhan Oui frère ça marche si vous avez un problème n'hésitez pas à me demander .. merci
Android Sanaullah
1
salut @AndroidSanaullah, pouvez-vous expliquer la première partie du code serveur, où le mettez-vous réellement, je suis confronté au même problème mais je ne comprends pas très bien la partie serveur, utilisez-vous Postman?
Shid
curl est utilisé pour la demande et tous les paramètres lui sont transmis. @ Shid
Android Sanaullah
2

Supprimez complètement la charge utile de notification de votre demande de serveur. Envoyez uniquement des données et gérez-les onMessageReceived(), sinon votre onMessageReceivedne sera pas déclenché lorsque l'application est en arrière-plan ou supprimée.

Voici ce que j'envoie du serveur:

{
  "data":{
    "id": 1,
    "missedRequests": 5
    "addAnyDataHere": 123
  },
  "to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......"
}

Ainsi, vous pouvez recevoir vos données onMessageReceived(RemoteMessage message)comme ceci: (disons que je dois obtenir l'identifiant)

Object obj = message.getData().get("id");
        if (obj != null) {
            int id = Integer.valueOf(obj.toString());
        }

Et de même, vous pouvez obtenir toutes les données que vous avez envoyées depuis le serveur onMessageReceived().

Zohab Ali
la source
2

Le moyen facile d'envoyer des messages même si l'application est en arrière-plan et au premier plan comme suit: - Pour envoyer un message à l'aide de l'API, vous pouvez utiliser un outil appelé AdvancedREST Client, c'est une extension chrome et envoyer un message avec les paramètres suivants.

Lien de l'outil client Rest: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

utilisez cette URL: - https://fcm.googleapis.com/fcm/send Content-Type: application / json Autorisation: clé = votre clé de serveur de ou clé d'authentification (voir ci-dessous réf)

{ "data": {
    "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg",
    "message": "Firebase Push Message Using API"
    "AnotherActivity": "True"
     },
  "to" : "device id Or Device token"
}

La clé d'autorisation peut être obtenue en visitant la console des développeurs Google et en cliquant sur le bouton Informations d'identification dans le menu de gauche de votre projet. Parmi les clés d'API répertoriées, la clé de serveur sera votre clé d'autorisation.

Et vous devez mettre tokenID du récepteur dans la section «à» de votre demande POST envoyée à l'aide de l'API.

Syed Danish Haider
la source
2

vous voulez travailler surMessageReceived (RemoteMessage remoteMessage) en arrière-plan envoyer uniquement la partie de notification de partie de données ceci:

"data":    "image": "",    "message": "Firebase Push Message Using API", 

"AnotherActivity": "True", "à": "ID de périphérique ou jeton de périphérique"

Par cela, onMessageRecivied est l'arrière-plan et le premier plan des appels, pas besoin de gérer la notification en utilisant le plateau de notification sur votre activité de lanceur. Gérez la charge utile des données en utilisant ceci:

  public void onMessageReceived(RemoteMessage remoteMessage)
    if (remoteMessage.getData().size() > 0) 
    Log.d(TAG, "Message data payload: " + remoteMessage.getData());      
user3385125
la source
1

Réponse de juin 2018 -

Vous devez vous assurer qu'il n'y a pas de mot-clé "notification" n'importe où dans le message. N'incluez que les «données» et l'application pourra gérer le message dans onMessageReceived, même en arrière-plan ou tué.

Utilisation des fonctions cloud:

const message = {
    token: token_id,   // obtain device token id by querying data in firebase
    data: {
       title: "my_custom_title",
       body:  "my_custom_body_message"
       }
    }


return admin.messaging().send(message).then(response => {
    // handle response
});

Ensuite, dans votre onMessageReceived (), dans votre classe étendant com.google.firebase.messaging.FirebaseMessagingService:

if (data != null) {
  Log.d(TAG, "data title is: " + data.get("title");
  Log.d(TAG, "data body is: " + data.get("body");
}

// build notification using the body, title, and whatever else you want.
Jeff Padgett
la source
avez-vous une source, est-ce sûr?
Yogesh Rathi
C'est sûr, je l'utilise dans mes applications. Cependant, 6 mois depuis la publication, je ne me souviens pas de la source - j'imagine que c'est la documentation Firebase.
Jeff Padgett
1

Selon OAUTH 2.0:

Il y aura un problème d'authentification pour ce cas parce que FCM utilise maintenant OAUTH 2

J'ai donc lu la documentation de Firebase et, selon la documentation, une nouvelle façon de publier un message de données est;

POST: https://fcm.googleapis.com/v1/projects/YOUR_FIREBASEDB_ID/messages:send

En-têtes

Key: Content-Type, Value: application/json

Auth

Bearer YOUR_TOKEN 

Exemple de corps

{
   "message":{
    "topic" : "xxx",
    "data" : {
         "body" : "This is a Firebase Cloud Messaging Topic Message!",
         "title" : "FCM Message"
          }
      }
 }

Dans l'url, il y a un identifiant de base de données que vous pouvez trouver sur votre console Firebase. (Aller aux projets)

Et maintenant, prenons notre jeton (il ne sera valide que 1 heure):

Tout d'abord dans la console Firebase, ouvrez Paramètres> Comptes de service . Cliquez sur Générer une nouvelle clé privée , stockez en toute sécurité le fichier JSON contenant la clé. J'avais besoin de ce fichier JSON pour autoriser manuellement les demandes de serveur. Je l'ai téléchargé.

Ensuite, je crée un projet node.js et utilise cette fonction pour obtenir mon jeton;

var PROJECT_ID = 'YOUR_PROJECT_ID';
var HOST = 'fcm.googleapis.com';
var PATH = '/v1/projects/' + PROJECT_ID + '/messages:send';
var MESSAGING_SCOPE = 'https://www.googleapis.com/auth/firebase.messaging';
var SCOPES = [MESSAGING_SCOPE];

  router.get('/', function(req, res, next) {
      res.render('index', { title: 'Express' });
      getAccessToken().then(function(accessToken) {
        console.log("TOKEN: "+accessToken)
      })

    });

function getAccessToken() {
return new Promise(function(resolve, reject) {
    var key = require('./YOUR_DOWNLOADED_JSON_FILE.json');
    var jwtClient = new google.auth.JWT(
        key.client_email,
        null,
        key.private_key,
        SCOPES,
        null
    );
    jwtClient.authorize(function(err, tokens) {
        if (err) {
            reject(err);
            return;
        }
        resolve(tokens.access_token);
    });
});
}

Maintenant, je peux utiliser ce jeton dans ma demande de publication. Ensuite, je poste mon message de données, et il est désormais géré par mes applications sur la fonction MessageMessage.

Ozan
la source
La réponse acceptée fonctionne, l'authentification par jeton Barer n'est pas le chemin, vous devez lire ceci pour l'essayer avec Postman: stackoverflow.com/questions/45309674/…
Carlos Jesus Arancibia Taborga
1

Depuis 2019, Google Firebase a un grand changement dans leurs API, je veux dire: 'com.google.firebase:firebase-messaging:18.0.0'

dans 18.0.0, ils ont été supprimés MyFirebaseInstanceIDServiceet vous devez obtenir un jeton, MyFirebaseMessagingServiceil vous suffit donc d'écrire:

@Override
public void onNewToken(String token) {
    Log.d(TAG, "Refreshed token: " + token);

}

et aussi dans votre AndroidManifest.xml, vous devez supprimer:

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

Il est également recommandé de définir des valeurs par défaut pour personnaliser l'apparence des notifications. Vous pouvez spécifier une icône par défaut personnalisée et une couleur par défaut personnalisée qui sont appliquées lorsque des valeurs équivalentes ne sont pas définies dans la charge utile de notification.

Ajoutez ces lignes à l'intérieur de la balise d'application pour définir l'icône par défaut personnalisée et la couleur personnalisée:

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_notification" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/push_channel" />

Maintenant, pour gérer les messages de notification dans une application en arrière-plan, vous devez définir une intention dans votre première activité, même s'il s'agit de SplashScreen. Lorsque votre application est en arrière-plan, Android dirige les messages de notification vers la barre d'état système. Un utilisateur tapant sur la notification ouvre le lanceur d'applications par défaut.

par exemple, si votre Json est comme ça:

 "data": {
"message": "2",
"title": "1",
"pushType" : "banner",
"bannerLink": "http://www.google.com",
"image" : "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"}

il vous suffit d'écrire une intention simple pour obtenir ces valeurs:

        Bundle extras = intent.getExtras();
        String bannerLink = extras.getString("bannerLink");
        ...
        String channelId = extras.getString("channelId");
Mohammad Mirzakhani
la source
0

En plus des réponses ci-dessus, si vous testez des notifications push à l'aide de la console FCM , la clé et l'objet 'données' ne sont pas ajoutés au groupe de notifications push. Vous ne recevrez donc pas de notification push détaillée lorsque l'application est en arrière-plan ou supprimée.

Dans ce cas, vous devez opter pour votre console d'administration principale pour tester le scénario d'arrière-plan de l'application.

Ici, vous aurez ajouté la clé «data» à votre bundle push. ainsi, une poussée détaillée sera affichée comme prévu. J'espère que cela aide peu.

Max Droid
la source
0

En utilisant ce code, vous pouvez obtenir la notification en arrière-plan / au premier plan et également mettre l'action:

//Data should come in this format from the notification
{
  "to": "/xyz/Notifications",
  "data": {
      "key1": "title notification",
      "key2": "description notification"
  }
}

Dans l'application, utilisez ce code:

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
      String key1Data = remoteMessage.getData().get("key1");
      // use key1Data to according to your need
    }
Ashish Kumar
la source
// Les données doivent provenir de ce format de la notification {"à": "/ xyz / Notifications", "data": {"key1": "title notification", "key2": "description notification"}} Comment écrire ce code dans le service php?
Tabish khan
-3

Il y aura deux types de notifications

  1. Afficher la notification - Seules les notifications d'affichage seront affichées, seule l'application n'est pas ouverte et son dans la pile d'applications.
  2. Notification de données - le rappel entrera dans la méthode onMessageReceived de firebasemessagingservice et cela fonctionnera lorsque l'application est en arrière-plan, au premier plan ou en mode tué.

Vous devez utiliser les notifications de données pour gérer la notification lorsque l'application est en arrière-plan.

abhi.nalavade
la source
-5

J'ai rencontré le même problème et recompilé la bibliothèque Firebase et l'empêché d'envoyer des notifications lorsque l'application est en arrière-plan

* bibliothèque https://github.com/erdalceylan/com-google-firebase-messaging

 dependencies {
        compile 'com.google.firebase:firebase-core:11.2.0'
        compile 'com.github.erdalceylan:com-google-firebase-messaging:v1-11.2.0'
    }

*

@WorkerThread
public void onMessageReceived(RemoteMessage var1) {
  //your app is in background or foreground all time calling
}

l'espoir aide. Bonne chance

Erdal CEYLAN
la source
2
Réponse
inutile
2
C'est une horrible suggestion.
vsecades