it-swarm.com.de

So behandeln Sie die Benachrichtigung, wenn sich die App in Firebase im Hintergrund befindet

Hier ist mein Manifest

    <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>

Wenn sich die App im Hintergrund befindet und eine Benachrichtigung eingeht, wird die Standardbenachrichtigung angezeigt und der Code onMessageReceived wird nicht ausgeführt.

Hier ist mein onMessageReceived Code. Dies ruft auf, wenn meine App im Vordergrund ausgeführt wird, nicht wenn die App im Hintergrund läuft. Wie führe ich diesen Code aus, wenn sich die App auch im Hintergrund befindet?

// [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]
311
Parth Patel

1. Warum passiert das?

Es gibt zwei Arten von Nachrichten in FCM (Firebase Cloud Messaging):

  1. Display Messages: Diese Nachrichten lösen den onMessageReceived() Callback nur aus, wenn sich Ihre App in Vordergrund befindet.
  2. Data Messages: Diese Nachrichten lösen onMessageReceived() callback even aus, wenn sich Ihre App in Vordergrund/Hintergrund/beendet befindet

Das Firebase-Team hat noch keine Benutzeroberfläche entwickelt, um data-messages an Ihre Geräte zu senden.

2. Wie geht das?

Um dies zu erreichen, müssen Sie eine POST-Anforderung an die folgende URL ausführen:

POSThttps://fcm.googleapis.com/fcm/send

Kopfzeilen

  • Key:Content-Type, Wert:application/json
  • Key:Authorization, Value:key=<your-server-key>

Körper mit Themen

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

Oder wenn Sie es an bestimmte Geräte senden möchten

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


HINWEIS: Stellen Sie sicher, dass Sie keine JSON-Taste notification.__ hinzufügen. 
HINWEIS: Um Ihren Serverschlüssel zu erhalten, können Sie ihn in der Firebase-Konsole finden: Your project -> settings -> Project settings -> Cloud messaging -> Server Key

3. Wie gehe ich mit der Push-Benachrichtigung um?

So behandeln Sie die empfangene Nachricht:

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

     // Manage data
}
526
Antonio

So erstellen Sie eine Firebase-Bibliothek, um Ihre onMessageReceived () in den folgenden Fällen aufzurufen

  1. App im Vordergrund
  2. App im Hintergrund
  3. App wurde getötet

sie dürfen den JSON-Schlüssel 'notification' nicht in Ihre Anfrage einbinden, sondern "data" verwenden, siehe unten.

Die folgende Nachricht ruft Ihre onMessageReceived () nicht auf, wenn sich Ihre App im Hintergrund befindet oder beendet wurde und Sie Ihre Benachrichtigung nicht anpassen können.

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

stattdessen wird dies funktionieren

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

Grundsätzlich wird die Nachricht mit dem Argument RemoteMessage zusammen mit Ihrem Datenobjekt als Map gesendet. Anschließend können Sie die Benachrichtigung in onMessageReceived wie im Snippet hier verwalten

@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
    */
}

Ich habe das Gefühl, dass alle Antworten unvollständig sind, aber alle haben etwas, das Sie benötigen, um eine Benachrichtigung zu verarbeiten, die Daten enthält, wenn sich Ihre App im Hintergrund befindet.

Folgen Sie diesen Schritten und Sie können Ihre Benachrichtigungen bearbeiten, wenn sich Ihre App im Hintergrund befindet.

1.Fügen Sie einen Intent-Filter wie folgt hinzu:

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

zu einer Aktivität, die Sie die Benachrichtigungsdaten verarbeiten möchten.

  1. Benachrichtigungen mit dem nächsten Format senden:

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

Der Schlüssel hier ist hinzufügen 

"click_action" : ".MainActivity"

dabei ist .MainActivity die Aktivität mit dem in Schritt 1 hinzugefügten Absichtsfilter.

  1. Erhalten Sie "Daten" -Informationen aus der Benachrichtigung in onCreate von ".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
        }
    }
    

Und das sollte alles sein, was Sie tun müssen. Ich hoffe das hilft jemandem :)

74
Daniel S.

Nach docs

Verarbeiten Sie Nachrichten in einer Hintergrund-App

Wenn sich Ihre App im Hintergrund befindet, leitet Android die Benachrichtigung Nachrichten in der Taskleiste. Ein Benutzer, der auf die Benachrichtigung tippt, öffnet die App-Starter standardmäßig.

Dies umfasst Nachrichten, die sowohl Benachrichtigungen als auch Daten enthalten Nutzlast. In diesen Fällen wird die Benachrichtigung an .__ des Geräts übermittelt. In der Taskleiste wird die Datennutzlast in den Extras des .__ ausgeliefert. Absicht Ihrer Launcher-Aktivität.

Wenn Sie Ihre App öffnen und eine bestimmte Aktion ausführen möchten, setzen Sie click_action in der Benachrichtigungsnutzlast und ordnen Sie es einer Absicht zu filtern Sie in der Aktivität, die Sie starten möchten. Stellen Sie beispielsweise .__ ein. Klicken Sie auf OPEN_ACTIVITY_1, um einen Intent-Filter wie den .__ auszulösen. folgende:

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

Bearbeiten:

Basierend auf diesem Thread

Sie können mit der Firebase-Konsole keine Click_action-Payload festlegen. Sie können es mit einem curl-Befehl oder einem benutzerdefinierten http-Server testen

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\"}}"
31
Shubhank

Laut der Firebase-Dokumentation in Send Downstream mittels Firebase gibt es zwei Arten von Nutzdaten:

  1. Daten

    Dieser Parameter gibt die benutzerdefinierten Schlüssel/Wert-Paare der Nutzdaten der Nachricht an. Die Client-App ist für die Verarbeitung von Datennachrichten verantwortlich. Datennachrichten haben nur benutzerdefinierte Schlüssel-Wert-Paare.

  2. Benachrichtigung

    Dieser Parameter gibt die vordefinierten, für den Benutzer sichtbaren Schlüssel-Wert-Paare der Benachrichtigungsnutzdaten an. FCM zeigt die Nachricht automatisch im Namen der Client-App an Endgeräte an. Benachrichtigungsnachrichten verfügen über vordefinierte, für Benutzer sichtbare Schlüssel.

Wenn Sie sich im Vordergrund befinden, können Sie die Daten in FCM mithilfe von onMessageReceived () abrufen. Sie können Ihre Daten aus data - Nutzdaten abrufen.

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

Wenn Sie sich im Hintergrund befinden, zeigt FCM eine Benachrichtigung in der Taskleiste an, basierend auf den Informationen von notification. Titel, Nachricht und Symbol, die für die Benachrichtigung in der Taskleiste verwendet wurden, werden von der Nutzlast notification abgerufen.

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

Diese notification - Nutzlast wird verwendet, wenn Sie die Benachrichtigung im Systemtray automatisch anzeigen möchten, wenn sich Ihre App im Hintergrund befindet .. Um Daten zu erhalten, wenn sich Ihre App im Hintergrund befindet, sollten Sie click_action in notification hinzufügen Nutzlast.

Wenn Sie Ihre App öffnen und eine bestimmte Aktion ausführen möchten [im Hintergrund], legen Sie click_action in der Benachrichtigungsnutzlast fest und ordnen Sie diese einem Absichtsfilter in der Aktivität zu, die Sie starten möchten. Setzen Sie beispielsweise click_action auf OPEN_ACTIVITY_1, um einen Intent-Filter wie folgt auszulösen:

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

Platzieren Sie diesen Intent-Filter in Ihrem Manifest innerhalb des Anwendungs-Tags. Wenn Sie auf die Benachrichtigung klicken, wird die App geöffnet und Sie gelangen direkt zu der Aktivität, die Sie in click_action definieren, in diesem Fall "OPEN_ACTIVTY_1" . Und innerhalb dieser Aktivität können Sie die Daten abrufen:

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

Ich verwende FCM für meine Android-App und verwende beide Nutzdaten. Hier ist das von mir verwendete Beispiel von JSON:

{
  "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"
   }
}
25
Hendy Evan

Da der display-messages, der von der Firebase Notification UI gesendet wird, nur funktioniert, wenn sich Ihre App im Vordergrund befindet. Für data-messages ist ein Aufruf von POST an FCM erforderlich.

Schritte

  1. Installieren Sie den Advanced Rest Client in der Google Chrome-Erweiterung  enter image description here

  2. Fügen Sie die folgenden Header hinzu 

    Key: Inhaltstyp, Value: application/json

    Key: Berechtigung, Value: key = "Ihr Server-Schlüssel"  enter image description here

  3. Füge den Körper hinzu

    • Bei Verwendung von Themen:

      {
          "to" : "/topics/topic_name",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
          }
      }
      
    • Bei Verwendung der Registrierungs-ID:

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

Das ist es!. Hören Sie jetzt wie üblich onMessageReceived-Rückruf.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}
19
Anirudh Ramanan

Um die Nachricht im Hintergrund zu erfassen, müssen Sie eine BroadcastReceiver verwenden.

public class FirebaseDataReceiver extends WakefulBroadcastReceiver {

    private final String TAG = "FirebaseDataReceiver";

    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "I'm in!!!");
        Bundle dataBundle = intent.getBundleExtra("data");
        Log.d(TAG, dataBundle.toString());
    }
}

und fügen Sie dies zu Ihrem Manifest hinzu:

<receiver
      Android:name="MY_PACKAGE_NAME.FirebaseDataReceiver"
      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>
15
Romulano
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}

wird nicht jedes Mal aufgerufen, wenn die App in forground ist

es gibt eine Überschreibungsmethode, die diese Methode jedes Mal aufgerufen wird, unabhängig davon, welche App im Vordergrund oder Hintergrund ist oder beendet wurde. Diese Methode ist jedoch mit dieser Firebase-API-Version verfügbar 

dies ist die Version, die Sie von Gradle importieren müssen

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

das ist die Methode

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

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


}

mit der vorherigen Firebase-API war diese Methode nicht vorhanden. In diesem Fall befand sich fire base selbst, wenn sich die App im Hintergrund befindet. Jetzt haben Sie diese Methode Was immer Sie tun möchten ... Sie können es hier in dieser Methode ..... 

wenn Sie eine frühere Version verwenden, beginnt die Standardaktivität In diesem Fall können Sie Daten auf dieselbe Weise abrufen 

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

// Mach was du willst .... }

im Allgemeinen ist dies die Struktur vom Server, die wir in einer Benachrichtigung erhalten 

{
    "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": "......."
    }
}

es liegt an dir, wie du diesen Datenschlüssel geben willst, oder du möchtest eine Benachrichtigung geben, was du geben kannst ....... was auch immer du hier mit demselben Schlüssel geben wirst, erhältst du diese Daten ..... .... 

es gibt wenige Fälle, in denen ur keine Klickaktion sendet, wenn u auf die Benachrichtigungs-Standardaktivität klickt. Wenn Sie jedoch Ihre spezifische Aktivität öffnen möchten, während sich die App im Hintergrund befindet, können Sie Ihre Aktivität über die handleIntent-Methode aufrufen wird jedes Mal aufgerufen 

15
Avinash Jadaun

Laut den Unterlagen: 17. Mai 2017

Wenn sich Ihre App im background befindet, wird Android Leitet Benachrichtigungsnachrichten in die Taskleiste. Ein Benutzer tippt auf Benachrichtigung öffnet den App-Starter standardmäßig.

Dies umfasst Nachrichten, die sowohl notification als auch data payload .__ enthalten. (und alle von der Benachrichtigungskonsole gesendeten Nachrichten). In diesen In diesem Fall wird die Benachrichtigung an die Systemablage des Geräts übermittelt, und Die Datennutzlast wird in den Extras Ihrer Absicht angegeben Launcher-Aktivität.

Sie sollten also die Payload-Benachrichtigung + Daten verwenden:

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

Es ist nicht notwendig, click_action zu verwenden. Sie sollten sich nur aus der Absicht der LAUNCHER-Aktivität 

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

Java-Code sollte in der Methode onCreate auf MainActivity enthalten sein:

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

Sie können sowohl die Payload-Benachrichtigung + -Daten von Firebase Notifications Console testen. Vergessen Sie nicht, benutzerdefinierte Datenfelder im Abschnitt Erweiterte Optionen auszufüllen

9
Mihuilk

Hier sind klarere Konzepte über die Firebase-Nachricht. Ich habe es von ihrem Support-Team gefunden. 

Firebase hat drei Nachrichtentypen:

Benachrichtigungsnachrichten: Die Benachrichtigungsnachricht funktioniert im Hintergrund oder Vordergrund. Wenn sich die App im Hintergrund befindet, werden Benachrichtigungsmeldungen an die Taskleiste gesendet. Wenn sich die App im Vordergrund befindet, werden Nachrichten von onMessageReceived() oder didReceiveRemoteNotification callbacks verarbeitet. Dies sind im Wesentlichen sogenannte Anzeigemeldungen.

Datennachrichten: Auf Android-Plattformen können Datennachrichten im Hintergrund und Vordergrund arbeiten. Die Datennachricht wird von onMessageReceived () verarbeitet. Eine plattformspezifische Anmerkung wäre hier: Unter Android kann die Datennutzlast in dem Intent abgerufen werden, das zum Starten Ihrer Aktivität verwendet wird. Wenn Sie "click_action":"launch_Activity_1" haben, können Sie diese Absicht nur über getIntent() von Activity_1 abrufen.

Nachrichten mit Benachrichtigungs- und Datennutzlasten: Im Hintergrund empfangen Apps die Benachrichtigungsnutzdaten im Benachrichtigungsbereich und behandeln die Datennutzlasten nur, wenn der Benutzer die Benachrichtigung antippt. Im Vordergrund empfängt Ihre App ein Nachrichtenobjekt mit beiden verfügbaren Nutzdaten. Zweitens wird der click_action-Parameter häufig in der Benachrichtigungsnutzlast und nicht in der Datennutzlast verwendet. Bei Verwendung in Data Payload wird dieser Parameter als benutzerdefiniertes Schlüssel-Wert-Paar behandelt. Daher müssen Sie eine benutzerdefinierte Logik implementieren, damit sie wie beabsichtigt funktioniert.

Außerdem empfehle ich Ihnen, die onMessageReceived-Methode (siehe Datennachricht) zu verwenden, um das Datenpaket zu extrahieren. Nach Ihrer Logik habe ich das Bündelobjekt überprüft und den erwarteten Dateninhalt nicht gefunden. Hier ist ein Hinweis auf einen ähnlichen Fall, der für mehr Klarheit sorgen könnte.

Für weitere Informationen besuchen Sie meinen diesen Thread

9

2017 aktualisierte Antwort

Hier ist eine klare Antwort aus den docs dazu:

 enter image description here

8
pulp_fiction

Ich habe die Szenarien herausgefunden,

Wenn sich app in foreground befindet, wird die onMessageReceived () - Methode vom FirebaseService aufgerufen, sodass das in der Serviceklasse definierte pendingIntent aufgerufen wird.

Und wenn sich die App in background befindet, wird erste Aktivität aufgerufen.

Wenn Sie nun eine splash-Aktivität verwenden, muss muss beachten, dass splashactivity aufgerufen wird, andernfalls, wenn keine splashActivity vorhanden ist, wird die erste Aktivität aufgerufen.

Dann müssen Sie getIntent () der firstActivity überprüfen, um zu sehen, ob es ein bundle . Hat. Wenn alles in Ordnung ist, werden Sie sehen, dass dort Bündel mit Werten eingetragen ist. Wenn der Wert in data tag, das vom Server gesendet wird, sieht folgendermaßen aus: 

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

In der ersten Aktivität sehen Sie dann: Dort gibt es eine gültige Absicht (getIntent () ist nicht null), ein gültiges Bündel und ein inneres Bündel. Dort wird die gesamte oben erwähnte JSON mit data alskey.

In diesem Szenario sieht der Code zum Extrahieren von Werten folgendermaßen aus:

    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();
                }


            }
        }

Einfache Zusammenfassung wie diese

  • wenn Ihre App läuft;

    onMessageReceived()
    

ist Auslöser.

  • wenn Ihre App nicht läuft (durch Wischen getötet);

    onMessageReceived()
    

wird nicht direkt ausgelöst und ausgeliefert. Wenn Sie ein spezielles Schlüssel-Wert-Paar haben. Sie arbeiten nicht, weil onMessageReceived () nicht funktioniert. 

Ich habe diesen Weg gefunden.

Fügen Sie in Ihrer Launcher-Aktivität diese Logik ein:

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
    }
}

suchen Sie in diesem if-Block nach Ihren Schlüsseln gemäß der Firebase-Benutzeroberfläche.

In diesem Beispiel meinen Schlüssel und Wert wie oben; (Entschuldigung für Sprache =))  enter image description here

Wenn mein Code funktioniert, bekomme ich "com.rda.note". 

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

mit dieser Codezeile habe ich meine Anwendung geschlossen und den Google Play Market geöffnet

glückliche Codierung =)

6
Arda

Vielen Dank an alle von Ihnen für Ihre Antworten. Aber ich habe das durch Senden gelöst datennachricht anstatt zu senden Benachrichtigung. Servercode

<?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;

?>

Und die Daten in onMessageReceived abgefangen

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());
}
}
3

Die einfache Methode zum Senden von Nachrichten, auch wenn sich die App im Hintergrund und Vordergrund befindet, ist wie folgt: - Zum Senden einer Nachricht mithilfe der API können Sie ein Tool namens AdvancedREST Client (eine Chrome-Erweiterung) verwenden und eine Nachricht mit folgendem senden Parameter.

Rest-Client-Tool Link: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

verwenden Sie diese URL: - https://fcm.googleapis.com/fcm/send - Inhaltstyp: application/json Autorisierung: key = Ihr Serverschlüssel von oder Autorisierungsschlüssel (siehe unten) )

{ "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"
}

Den Autorisierungsschlüssel erhalten Sie über die Google Entwicklerkonsole. Klicken Sie für Ihr Projekt im linken Menü auf die Schaltfläche Anmeldeinformationen. Unter den aufgeführten API-Schlüsseln ist der Serverschlüssel Ihr Autorisierungsschlüssel.

Und Sie müssen die tokenID des Empfängers in den "to" -Abschnitt Ihrer POST -Anforderung eingeben, die mit der API gesendet wurde.

2

Entferne die Benachrichtigungsnutzlast vollständig von deiner Serveranfrage. Senden Sie nur Daten und behandeln Sie sie in onMessageReceived(), andernfalls wird Ihre onMessageReceived nicht ausgelöst, wenn sich die App im Hintergrund befindet oder beendet wird.

Folgendes sende ich vom Server:

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

So können Sie Ihre Daten in onMessageReceived(RemoteMessage message) wie folgt empfangen: (Nehmen wir an, ich muss die ID erhalten)

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

Ebenso können Sie alle Daten, die Sie vom Server gesendet haben, innerhalb von onMessageReceived() abrufen.

2
Zohab Ali

sie möchten anMessageReceived (RemoteMessage remoteMessage) im Hintergrund arbeiten, senden Sie nur einen Datenteilbenachrichtigungsteil: 

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

"AnotherActivity": "True", "bis": "Geräte-ID oder Gerätetoken" 

Bei diesem Aufruf von onMessageRecivied ist der Hintergrund und Vordergrund des Anrufs nicht erforderlich, um die Benachrichtigung über den Benachrichtigungsbereich in der Launcher-Aktivität zu behandeln. Behandeln Sie die Datennutzdaten wie folgt:
public void onMessageReceived (RemoteMessage remoteMessage) if (remoteMessage.getData (). size ()> 0) Log.d (TAG, "Message Data Payload:") + remoteMessage.getData ()); 

1
user3385125

Juni 2018 Antwort - 

Sie müssen sicherstellen, dass sich in der Nachricht an keiner Stelle ein Benachrichtigungsschlüsselwort befindet. Nur "Daten" einschließen, und die App kann die Nachricht in onMessageReceived verarbeiten, auch wenn sie sich im Hintergrund befindet oder beendet ist.

Verwenden von Cloud-Funktionen:

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
});

Dann in deiner onMessageReceived (), in deiner Klasse, die com.google.firebase.messaging.FirebaseMessagingService erweitert:

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.
1
Jeff Padgett

Aktualisierte Antwort gemäß OAUTH 2.0:  

Die akzeptierte Antwort funktioniert nicht mehr (Fehler 401) .. Es wird ein Auth-Problem für diesen Fall auftreten, da FCM jetzt OAUTH 2 verwendet

Also habe ich die Firebase-Dokumentation gelesen und laut Dokumentation eine neue Methode zum Versenden von Datennachrichten.

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

Kopfzeilen

Key: Content-Type, Value: application/json

Auth

Bearer YOUR_TOKEN 

Beispiel Körper

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

In der URL befindet sich die Datenbank-ID, die Sie auf Ihrer Firebase-Konsole finden können. (Gehe Projektabrechnungen)

Und nun nehmen wir unser Token (es gilt nur 1 Stunde):

Öffnen Sie zunächst in der Firebase-Konsole Einstellungen> Dienstkonten . Klicken Sie auf Neuen privaten Schlüssel generieren , und speichern Sie die JSON-Datei, die den Schlüssel enthält, sicher. Ich benötigte diese JSON-Datei, um Serveranforderungen manuell zu autorisieren. Ich habe es heruntergeladen.

Dann erstelle ich ein node.js-Projekt und verwende diese Funktion, um mein Token zu erhalten.

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);
    });
});
}

Jetzt kann ich dieses Token in meiner Post-Anfrage verwenden. Dann poste ich meine Datennachricht und diese wird jetzt von meiner Apps-Funktion onMessageReceived verwaltet.

0
Ozan

Seit 2019 hat Google Firebase große Änderungen an den APIs vorgenommen. Ich meine: 'com.google.firebase:firebase-messaging:18.0.0'

in 18.0.0 haben sie MyFirebaseInstanceIDService entfernt und Sie müssen das Token in MyFirebaseMessagingService abrufen, sodass Sie nur schreiben müssen:

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

}

und auch in deiner AndroidManifest.xml musst du entfernen:

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

Es wird außerdem empfohlen, Standardwerte festzulegen, um das Erscheinungsbild von Benachrichtigungen anzupassen. Sie können ein benutzerdefiniertes Standardsymbol und eine benutzerdefinierte Standardfarbe angeben, die angewendet werden, wenn in der Benachrichtigungsnutzlast keine entsprechenden Werte festgelegt sind.

Fügen Sie diese Zeilen in das Anwendungs-Tag ein, um das benutzerdefinierte Standardsymbol und die benutzerdefinierte Farbe festzulegen:

    <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" />

um Benachrichtigungsnachrichten in einer App im Hintergrund zu verarbeiten, sollten Sie in Ihrer ersten Aktivität einen Intent definieren, auch wenn es sich um SplashScreen handelt. Wenn sich Ihre App im Hintergrund befindet, leitet Android Benachrichtigungsnachrichten an die Taskleiste. Ein Benutzer, der auf die Benachrichtigung tippt, öffnet standardmäßig den App-Launcher.

zum Beispiel, wenn Ihr Json so ist:

 "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"}

sie müssen nur eine einfache Absicht schreiben, um diese Werte zu erhalten:

        Bundle extras = intent.getExtras();
        String bannerLink = extras.getString("bannerLink");
        ...
        String channelId = extras.getString("channelId");
0

Stand Juli 2019

Android compileSdkVersion 28, buildToolsVersion 28.0.3 und firebase-messaging: 19.0.1

Nachdem viele, viele Stunden lang alle anderen Fragen und Antworten zu StackOverflow durchgearbeitet und unzählige veraltete Lösungen ausprobiert worden waren, konnte diese Lösung Benachrichtigungen in den folgenden drei Szenarien anzeigen:

- App steht im Vordergrund:
Die Benachrichtigung wird von der onMessageReceived-Methode in meiner MyFirebaseMessagingService-Klasse empfangen

- App wurde beendet (läuft nicht im Hintergrund): Die Benachrichtigung wird automatisch von FCM an die Benachrichtigungsleiste gesendet. Wenn der Benutzer die Benachrichtigung berührt, wird die App durch Aufrufen der Aktivität mit Android.intent.category.LAUNCHER im Manifest gestartet. Sie können den Datenteil der Benachrichtigung mit getIntent (). GetExtras () bei der onCreate () -Methode abrufen.

- App ist im Hintergrund: Die Benachrichtigung wird automatisch von FCM an die Benachrichtigungsleiste gesendet. Wenn der Benutzer die Benachrichtigung berührt, wird die App in den Vordergrund gerückt, indem die Aktivität mit Android.intent.category.LAUNCHER im Manifest gestartet wird. Da meine App in dieser Aktivität launchMode = "singleTop" enthält, wird die Methode onCreate () nicht aufgerufen, da bereits eine Aktivität derselben Klasse erstellt wurde. Stattdessen wird die Methode onNewIntent () dieser Klasse aufgerufen und Sie erhalten den Datenteil von die Benachrichtigung dort mit intent.getExtras ().

Schritte: 1- Wenn Sie die Hauptaktivität Ihrer App folgendermaßen definieren:

<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- Fügen Sie diese Zeilen bei der onCreate () -Methode Ihrer MainActivity.class hinzu

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);
    }
}

und diese Methoden zur gleichen 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- Erstelle die Klasse MyFirebase wie folgt:

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- Erstellen Sie eine neue Klasse NotificationActivity.class wie folgt:

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- Fügen Sie diese Zeilen zu Ihrem App-Manifest in Ihren Tags hinzu

    <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- Fügen Sie diese Zeilen in Ihre Application.Java-Methode onCreate () oder in die MainActivity.class-Methode onCreate () ein:

      // 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));
  }

Erledigt.

Damit dies in den drei genannten Szenarien gut funktioniert, müssen Sie die Benachrichtigung von der Firebase-Webkonsole folgendermaßen senden:

Im Abschnitt Benachrichtigung: Benachrichtigungstitel = Titel, der im Benachrichtigungsdialog angezeigt werden soll (optional) Benachrichtigungstext = Nachricht, die dem Benutzer angezeigt werden soll (erforderlich). Im Abschnitt Ziel: App = Ihre Android -Anwendung und in Additional Optionsabschnitt: Android Notification Channel = default_channel_id Benutzerdefinierte Datenschlüssel: Titelwert: (hier derselbe Text wie im Titelfeld des Notification-Abschnitts) Schlüssel: Textkörperwert: (hier derselbe Text wie im Nachrichtenfeld von den Benachrichtigungsabschnitt): click_action value: .MainActivity Sound = Disabled
Läuft ab = 4 Wochen

Sie können es im Emulator mit API 28 mit Google Play debuggen.

Viel Spaß beim Codieren!

0
alvaro

Mit diesem Code können Sie die Benachrichtigung im Hintergrund/Vordergrund abrufen und auch Maßnahmen ergreifen:

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

In-App verwenden Sie diesen Code:

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
      String key1Data = remoteMessage.getData().get("key1");
      // use key1Data to according to your need
    }
0
Ashish Kumar
  // Place this code on your MainActivity,then you will get your payload
  // Handle possible data accompanying notification message.
    // [START handle_data_extras]
    if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Log.d(TAG, "Key: " + key + " Value: " + value);
        }
    }
0
baderkhane

Zusätzlich zu den obigen Antworten wird Wenn Sie Push-Benachrichtigungen mit FCM Console testen, werden der Datenschlüssel und das Objekt nicht zum Push-Benachrichtigungspaket hinzugefügt. So erhalten Sie keine detaillierte Push-Benachrichtigung, wenn die App im Hintergrund ist oder beendet wird.

In diesem Fall müssen Sie sich für die Back-End-Administrationskonsole entscheiden, um das App-Hintergrundszenario zu testen.

Hier haben Sie Ihrem Push-Paket einen Datenschlüssel hinzugefügt. So wird ausführlicher Push wie erwartet gezeigt. Hoffen Sie, dass dies wenigen hilft.

0
Max Droid