Firebase onMessageReceived wird nicht aufgerufen, wenn die App im Hintergrund angezeigt wird


232

Ich arbeite mit Firebase und teste das Senden von Benachrichtigungen von meinem Server an meine App, während sich die App im Hintergrund befindet. Die Benachrichtigung wurde erfolgreich gesendet, sie wird sogar im Benachrichtigungscenter des Geräts angezeigt. Wenn die Benachrichtigung jedoch angezeigt wird oder wenn ich darauf klicke, wird die onMessageReceived-Methode in meinem FCMessagingService niemals aufgerufen.

Als ich dies testete, während meine App im Vordergrund stand, wurde die Methode onMessageReceived aufgerufen und alles funktionierte einwandfrei. Das Problem tritt auf, wenn die App im Hintergrund ausgeführt wird.

Ist das beabsichtigtes Verhalten oder gibt es eine Möglichkeit, dies zu beheben?

Hier ist mein FBMessagingService:

import android.util.Log;

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

public class FBMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.i("PVL", "MESSAGE RECEIVED!!");
        if (remoteMessage.getNotification().getBody() != null) {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody());
        } else {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message"));
        }
    }
}

Wo befindet sich neben dem json-Body Ihr onTokenRefresh- Code? Haben Sie das Android-Setup abgeschlossen ?
Kato

4
Was meinst du mit dem JSON-Text der Benachrichtigung? Außerdem befindet sich mein onTokenRefresh-Code in meinem FirebaseInstanceID-Dienst.
Cyogenos

Können Sie die von Ihnen gesendete Beispielnutzlast veröffentlichen?
AL.


Sie können diesen Thread auch überprüfen stackoverflow.com/questions/39046270/…
Md. Sajedul Karim

Antworten:


144

Dies funktioniert wie beabsichtigt. Benachrichtigungsnachrichten werden nur dann an Ihren onMessageReceived-Rückruf gesendet, wenn sich Ihre App im Vordergrund befindet. Wenn sich Ihre App im Hintergrund befindet oder geschlossen ist, wird im Benachrichtigungscenter eine Benachrichtigungsnachricht angezeigt, und alle Daten aus dieser Nachricht werden an die Absicht übergeben , die gestartet wird, wenn der Benutzer auf die Benachrichtigung tippt.

Sie können eine click_action angeben, um die Absicht anzugeben, die gestartet werden soll, wenn der Benutzer auf die Benachrichtigung tippt. Die Hauptaktivität wird verwendet, wenn keine click_action angegeben ist.

Wenn die Absicht gestartet wird, können Sie die verwenden

getIntent().getExtras();

um einen Satz abzurufen, der alle Daten enthält, die zusammen mit der Benachrichtigungsnachricht gesendet wurden.

Weitere Informationen zur Benachrichtigung finden Sie in den Dokumenten .


6
Gibt es eine Möglichkeit, die Einstellung click_actionfestzulegen, wenn ich die Firebase-Benachrichtigungskonsole verwende?
Nii Laryea

6
ok, aber was ist, wenn die App beendet wird (kein Vordergrund oder Hintergrund)?
Michalu

3
Aber wie kann man die Benachrichtigung über das Verwerfen von Benutzern deaktivieren? Denn wenn der Benutzer es verwirft, bedeutet dies, dass alle Daten übersprungen werden ... Richtig?
Aleksey Timoshchenko

4
Richtig! Wenn Sie Benachrichtigungsnachrichten an Android senden, sollten die zugehörigen Daten Daten sein, die das Benachrichtigungserlebnis verbessern. Es sollten keine app-kritischen Daten sein. Verwenden Sie Datennachrichten für Daten, die die Anwendung benötigt, auch wenn der Benutzer die Benachrichtigung ablehnt.
Arthur Thompson

3
Das ist nicht ganz richtig. Wenn die Nachricht nur Daten und keine Benachrichtigungsnutzdaten enthält, wird die Nachricht IMMER an onMessageReceive übermittelt, wenn sich die App im Vordergrund befindet oder nicht.
JacksOnF1re

125

Entfernen Sie das notificationFeld vollständig aus Ihrer Serveranforderung. Nurdata senden und bearbeiten, onMessageReceived()sonst wird Ihr onMessageReceived()App nicht ausgelöst, wenn sich die App im Hintergrund befindet oder beendet wurde.

Vergessen Sie nicht, das "priority": "high"Feld in Ihre Benachrichtigungsanfrage aufzunehmen. Laut Dokumentation: Datennachrichten werden mit normaler Priorität gesendet, sodass sie nicht sofort eintreffen. es könnte auch das Problem sein.

Folgendes sende ich vom Server

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

So können Sie Ihre Daten auf onMessageReceived(RemoteMessage message)diese Weise empfangen ... Nehmen wir an, ich muss einen Ausweis erhalten

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

9
Ich habe festgestellt, dass die App, die vom Task-Manager gelöscht wurde, keine Benachrichtigung erhalten kann, wenn ich nur eine Datennachricht sende. Ist dies ein beabsichtigtes Verhalten?
Prabhjot Singh

2
Dies war die Lösung für mich, Nachrichten im Hintergrund zu empfangen!
Ray Hulha

5
In Oreo wird onMessageReceived nicht aufgerufen, wenn die App beendet wird. Ich habe nur Nutzdaten nur mit Daten. Hast du ein Update?
Samir Mangroliya

2
Klappt wunderbar!
ssk

3
Ich liebe dich sehr für diese Antwort: p
Ahmad Arslan

63

Diese Methode handleIntent () wurde abgeschrieben, sodass die Bearbeitung einer Benachrichtigung wie folgt erfolgen kann:

  1. Vordergrundstatus: Durch Klicken auf die Benachrichtigung wird die Aktivität der ausstehenden Absicht aufgerufen, die Sie bereitstellen, während Sie eine Benachrichtigung programmgesteuert erstellen, wie sie im Allgemeinen mit der Datennutzlast der Benachrichtigung erstellt wird.

  2. Hintergrund / getöteter Status - Hier erstellt das System selbst eine Benachrichtigung basierend auf der Benachrichtigungsnutzlast. Wenn Sie auf diese Benachrichtigung klicken, gelangen Sie zur Startaktivität der Anwendung, in der Sie problemlos Absichtsdaten in einer Ihrer Lebenszyklusmethoden abrufen können.


Danke dir!!! Ich habe ein paar Tage wegen dieses Problems verloren und dieses hat mich gerettet.
Igor Janković

wirklich die perfekte Lösung!
EduXavier

4
Ich verarbeite die Benachrichtigungsanzeigelogik in handleIntent (Intent intent). Wenn sich die App jedoch im Hintergrund befindet, werden 2 Benachrichtigungen angezeigt, eine, die ich erstellt habe, und eine andere, die standardmäßig die gesamte Nachricht aus der Benachrichtigung enthält.
Joyson

5
Genial, aber ich sehe OnMessageReceivedin diesem Fall keine Verwendung dafür !?
Alaa AbuZarifa

8
Ich habe com.google.firebase: firebase-messaging: 11.6.2 & handleIntent ist jetzt endgültig. Überprüfen Sie stackoverflow.com/questions/47308155/…
Ronak Poriya

30

Ich hatte das gleiche Problem. Es ist einfacher, die 'Datennachricht' anstelle der 'Benachrichtigung' zu verwenden. Die Datennachricht lädt immer die Klasse onMessageReceived.

In dieser Klasse können Sie mit dem Benachrichtigungsbuilder Ihre eigene Benachrichtigung erstellen.

Beispiel:

 @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
    }

    private void sendNotification(String messageTitle,String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT);

        long[] pattern = {500,500,500,500,500};

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setVibrate(pattern)
                .setLights(Color.BLUE,1,1)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

7
Danke. Ich habe meinen Servercode geändert und verwende "Daten" anstelle von "Benachrichtigung" und jetzt funktioniert es perfekt.
Mahesh Kavathiya

5
@Koot es funktioniert nur, wenn die App im Vordergrund ist, nicht wenn sie im Hintergrund ist. Kannst du mir helfen, dieses Ereignis in beiden Fällen auszulösen?
Anant Shah

@AnantShah Wie sieht Ihr POST auf dem Firebase-Server aus?
Koot

3
Hier gibt es tatsächlich drei mögliche Fälle. 1) App im Vordergrund. 2) App im Hintergrund. 3) App läuft nicht. Wie Sie sagen, wird in den ersten beiden Fällen eine "Daten" -Nachricht empfangen, im dritten Fall jedoch nicht , wenn die App nicht ausgeführt wird. Um alle drei Fälle zu behandeln, müssen Sie das Feld "Benachrichtigung" in der Nachricht festlegen. (Auch eine gute Idee, wenn Sie sowohl iOS- als auch Android-Clients unterstützen möchten)
Steve Moseley

1
Auch wenn die App nicht läuft, bekomme ich immer noch eine Nachricht vom Server über die Funktion onmessagereceived. Ich stimme Ihnen zu, dass es besser ist, "Benachrichtigung" zu verwenden, wenn Sie auch ios unterstützen möchten.
Koot

30

Hier finden Sie klarere Konzepte zur Firebase-Nachricht. Ich habe es von ihrem Support-Team gefunden.

Firebase hat drei Nachrichtentypen :

Benachrichtigungsnachrichten : Die Benachrichtigungsnachricht funktioniert im Hintergrund oder im Vordergrund. Wenn sich die App im Hintergrund befindet, werden Benachrichtigungsnachrichten an die Taskleiste gesendet. Wenn sich die App im Vordergrund befindet, werden Nachrichten von onMessageReceived()oder didReceiveRemoteNotificationRückrufe verarbeitet. Dies sind im Wesentlichen sogenannte Display-Nachrichten.

Datennachrichten : Auf der Android-Plattform können Datennachrichten im Hintergrund und im Vordergrund ausgeführt werden. Die Datennachricht wird von onMessageReceived () verarbeitet. Ein plattformspezifischer Hinweis wäre hier: Unter Android kann die Datennutzlast in der Absicht abgerufen werden, die zum Starten Ihrer Aktivität verwendet wird. Um dies zu erläutern, "click_action":"launch_Activity_1"können Sie diese Absicht getIntent()nur von abrufen Activity_1.

Nachrichten mit Benachrichtigungs- und Datennutzdaten : Im Hintergrund empfangen Apps die Benachrichtigungsnutzdaten in der Benachrichtigungsleiste und verarbeiten die Datennutzdaten nur, wenn der Benutzer auf die Benachrichtigung tippt. Im Vordergrund empfängt Ihre App ein Nachrichtenobjekt mit beiden verfügbaren Nutzdaten. Zweitens wird der Parameter click_action häufig in Benachrichtigungsnutzdaten und nicht in Datennutzdaten verwendet. Bei Verwendung innerhalb der Datennutzlast wird dieser Parameter als benutzerdefiniertes Schlüssel-Wert-Paar behandelt. Daher müssen Sie eine benutzerdefinierte Logik implementieren, damit er 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 Bundle-Objekt überprüft und den erwarteten Dateninhalt nicht gefunden. Hier ist ein Verweis auf einen ähnlichen Fall, der mehr Klarheit bieten könnte.

Auf der Serverseite sollte die Firebase-Benachrichtigung das folgende Format haben :

Die Serverseite sollte "Benachrichtigung" senden. -Objekt . Es fehlt ein "Benachrichtigungs" -Objekt in meinem, TargetActivitydas keine Nachricht verwendet hat getIntent().

Das richtige Nachrichtenformat ist unten angegeben:

{
 "data": {
  "body": "here is body",
  "title": "Title"
 },
"notification": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
 "to": "ffEseX6vwcM:APA91bF8m7wOF MY FCM ID 07j1aPUb"
}

Hier finden Sie klarere Konzepte zur Firebase-Nachricht. Ich habe es von ihrem Support-Team gefunden.

Für weitere Informationen besuchen Sie meinen diesen Thread und diesen Thread


3
Erwähnenswert ist, dass "Datennachrichten" nicht empfangen werden, wenn sich das Gerät im Deep-Doze-Modus befindet (eingeführt in Android 7.0). Sei vorsichtig mit denen!
Sameer J

21

Gemäß der Dokumentation zu Firebase Cloud Messaging. Wenn die Aktivität im Vordergrund steht, wird onMessageReceived aufgerufen. Wenn die Aktivität im Hintergrund oder geschlossen ist, wird im Benachrichtigungscenter eine Benachrichtigungsnachricht für die Aktivität des App-Starters angezeigt. Sie können Ihre benutzerdefinierte Aktivität per Klick auf Benachrichtigung aufrufen, wenn sich Ihre App im Hintergrund befindet, indem Sie die Rest-Service-API für Firebase-Nachrichten wie folgt aufrufen:

URL- https://fcm.googleapis.com/fcm/send

Methodentyp - POST

Header- Content-Type:application/json
Authorization:key=your api key

Körper / Nutzlast:

{ "notification": {
    "title": "Your Title",
    "text": "Your Text",
     "click_action": "OPEN_ACTIVITY_1" // should match to your intent filter
  },
    "data": {
    "keyname": "any value " //you can get this data as extras in your activity and this data is optional
    },
  "to" : "to_id(firebase refreshedToken)"
} 

Und damit können Sie in Ihrer App den folgenden Code in Ihre aufzurufende Aktivität einfügen:

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

Wo würde ich die Absicht erstellen und eine bestimmte Aktivität eröffnen lassen? Ich weiß, dass dies die Absicht OPEN_ACTIVITY_1 im Manifest registriert, aber wo nenne ich es eigentlich?
Cyogenos


Sollten wir eine Aktivität aus Intent-Filtern aufrufen? Oder manuell starten in onMessageReceived?
CoolMind

14

Die Methode onMessageReceived (RemoteMessage remoteMessage) wird basierend auf den folgenden Fällen aufgerufen.

  • FCM Reaktion mit Benachrichtigung und Datenblock:
{
  
"to": "device token list",
  "notification": {
    "body": "Body of Your Notification",
    "title": "Title of Your Notification"
  },
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}
  1. App im Vordergrund:

onMessageReceived (RemoteMessage remoteMessage) wird aufgerufen und zeigt LargeIcon und BigPicture in der Benachrichtigungsleiste an. Wir können den Inhalt von beiden lesen Benachrichtigung und Datenblock

  1. App im Hintergrund:

onMessageReceived (RemoteMessage remoteMessage) wird nicht aufgerufen. Die Taskleiste empfängt die Nachricht und liest Text und Titel aus dem Benachrichtigungsblock und zeigt die Standardnachricht und den Standardtitel in der Benachrichtigungsleiste an.

  • FCM Antwort Mit nur Datenblock:

In diesem Fall entfernen Sie Benachrichtigungsblöcke aus json

{
  
"to": "device token list",
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}

Lösung zum Aufrufen von onMessageReceived ()

  1. App im Vordergrund:

onMessageReceived (RemoteMessage remoteMessage) wird aufgerufen und zeigt LargeIcon und BigPicture in der Benachrichtigungsleiste an. Wir können den Inhalt von beiden lesen Benachrichtigung und Datenblock

  1. App im Hintergrund:

Wenn onMessageReceived (RemoteMessage remoteMessage) aufgerufen wird, empfängt die Taskleiste die Nachricht aufgrund von nicht Benachrichtigungsschlüssel nicht in der Antwort enthalten ist. Zeigt LargeIcon und BigPicture in der Benachrichtigungsleiste an

Code

 private void sendNotification(Bitmap bitmap,  String title, String 
    message, PendingIntent resultPendingIntent) {

    NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
    style.bigPicture(bitmap);

    Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

    NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    String NOTIFICATION_CHANNEL_ID = mContext.getString(R.string.default_notification_channel_id);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);

        notificationManager.createNotificationChannel(notificationChannel);
    }
    Bitmap iconLarge = BitmapFactory.decodeResource(mContext.getResources(),
            R.drawable.mdmlogo);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.mdmlogo)
            .setContentTitle(title)
            .setAutoCancel(true)
            .setSound(defaultSound)
            .setContentText(message)
            .setContentIntent(resultPendingIntent)
            .setStyle(style)
            .setLargeIcon(iconLarge)
            .setWhen(System.currentTimeMillis())
            .setPriority(Notification.PRIORITY_MAX)
            .setChannelId(NOTIFICATION_CHANNEL_ID);


    notificationManager.notify(1, notificationBuilder.build());


}

Referenzlink:

https://firebase.google.com/docs/cloud-messaging/android/receive


Der wichtigste Teil für Personen mit Hintergrundproblemen ist das Entfernen der Eigenschaft "Benachrichtigung" aus JSON, das vom Server gesendet wird. Dies löst das Problem. Vielen Dank.
Ramy M. Mousa

13

Ich habe das gleiche Problem. Wenn die App im Vordergrund steht, wird mein Hintergrunddienst ausgelöst, bei dem ich meine Datenbank basierend auf dem Benachrichtigungstyp aktualisieren kann. Die App tritt jedoch in den Hintergrund - der Standardbenachrichtigungsdienst sorgt dafür, dass die Benachrichtigung dem Benutzer angezeigt wird.

Hier ist meine Lösung, um die App im Hintergrund zu identifizieren und Ihren Hintergrunddienst auszulösen:

public class FirebaseBackgroundService extends WakefulBroadcastReceiver {

  private static final String TAG = "FirebaseService";

  @Override
  public void onReceive(Context context, Intent intent) {
    Log.d(TAG, "I'm in!!!");

    if (intent.getExtras() != null) {
      for (String key : intent.getExtras().keySet()) {
        Object value = intent.getExtras().get(key);
        Log.e("FirebaseDataReceiver", "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("gcm.notification.body") && value != null) {
          Bundle bundle = new Bundle();
          Intent backgroundIntent = new Intent(context, BackgroundSyncJobService.class);
          bundle.putString("push_message", value + "");
          backgroundIntent.putExtras(bundle);
          context.startService(backgroundIntent);
        }
      }
    }
  }
}

In der manifest.xml

<receiver android:exported="true" android:name=".FirebaseBackgroundService" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </receiver>

Getestet diese Lösung in der neuesten Android 8.0-Version. Vielen Dank


Warum soll diese FirebaseBackgroundService-Klasse verwendet werden? @ Nagendra Badiganti

Verwendungszweck dieses Codes öffentliche Klasse FirebaseBackgroundService erweitert WakefulBroadcastReceiver @Nagendra Badiganti

Erstellen Sie eine Serviceklasse in Ihrem Paket und registrieren Sie sich in Ihrer manifest.xml. Stellen Sie sicher, dass Sie den Filter für Ihre Benachrichtigungen haben. Da der Dienst für jede GCM-Benachrichtigung ausgelöst wird.
Nagendra Badiganti

firebase.google.com/docs/cloud-messaging/android/… Ich folge diesem Link. Ich muss diese Klasse hinzufügen, um eine Benachrichtigung zu erhalten. Nur Nachricht von Firebase erste Nachricht senden .. es heißt abgeschlossen, aber keine Benachrichtigung erhalten @Nagendra Badiganti

1
WakefulBroadcastReceiverist seit API-Level 26.1.0 veraltet.
Minoru

12

Wenn sich die App im Hintergrundmodus befindet oder inaktiv (getötet) ist und Sie auf Benachrichtigung klicken , sollten Sie in LaunchScreen nach der Nutzlast suchen (in meinem Fall ist der Startbildschirm MainActivity.java).

Suchen Sie in MainActivity.java auf onCreate nach Extras :

    if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Log.d("MainActivity: ", "Key: " + key + " Value: " + value);
        }
    }

Wie kann ich den Titel, den Text und die Daten der Benachrichtigung abrufen?
Md.Tarikul Islam

1
Danke, das ist die Antwort. @ Md.Tarikul Islam mit onMessageReceived () wie in dieser Frage erwähnt.
felixwcf

7

Überschreiben Sie die handleIntentMethode der FirebaseMessageServiceArbeiten für mich.

hier der Code in C # (Xamarin)

public override void HandleIntent(Intent intent)
{
    try
    {
        if (intent.Extras != null)
        {
            var builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            foreach (string key in intent.Extras.KeySet())
            {
                builder.AddData(key, intent.Extras.Get(key).ToString());
            }

            this.OnMessageReceived(builder.Build());
        }
        else
        {
            base.HandleIntent(intent);
        }
    }
    catch (Exception)
    {
        base.HandleIntent(intent);
    }
}

und das ist der Code in Java

public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }

            onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}

handleIntent () ist endgültig
Ettore

@Ettore Wie kann ich die handleIntent-Funktion aufrufen?
Hiroto

Die Methode wird aufgerufen, wenn Sie die Nachricht von Firebase erhalten. Sie können sie jedoch nicht überschreiben, da die Methode als endgültig deklariert ist. (Firebase 11.6.0)
Ettore

5

Standardmäßig wird die Startaktivität in Ihrer App gestartet, wenn sich Ihre App im Hintergrund befindet und Sie auf die Benachrichtigung klicken. Wenn Ihre Benachrichtigung einen Datenteil enthält, können Sie diese in derselben Aktivität wie folgt ausführen:

if(getIntent().getExtras()! = null){
  //do your stuff
}else{
  //do that you normally do
}

Wenn ich von mainActivity aus navigiere, wie funktioniert die Rückkehr zu einer bestimmten Aktivität?
Mac_Play

. @Uzair getIntent () getExtras () immer null bekommen, Haben Sie eine andere Lösung haben , wenn App wird bacground onMessageReceived Methode nicht angerufen?
user2025187

3

Wenn sich die App im Hintergrund befindet Fire-Base standardmäßig Handhabungsbenachrichtigung Wenn wir jedoch unsere benutzerdefinierte Benachrichtigung wünschen, müssen wir unsere Serverseite ändern, die für das Senden unserer benutzerdefinierten Daten verantwortlich ist (Datennutzlast).

Entfernen Sie die Benachrichtigungsnutzdaten vollständig von Ihrer Serveranforderung. Senden Sie nur Daten und verarbeiten Sie sie in onMessageReceived (). Andernfalls wird Ihre onMessageReceived nicht ausgelöst, wenn sich die App im Hintergrund befindet oder beendet wird.

Jetzt sieht Ihr serverseitiges Codeformat so aus:

{
  "collapse_key": "CHAT_MESSAGE_CONTACT",
  "data": {
    "loc_key": "CHAT_MESSAGE_CONTACT",
    "loc_args": ["John Doe", "Contact Exchange"],
    "text": "John Doe shared a contact in the group Contact Exchange",
    "custom": {
      "chat_id": 241233,
      "msg_id": 123
    },
    "badge": 1,
    "sound": "sound1.mp3",
    "mute": true
  }
}

HINWEIS : Siehe diese Zeile im obigen Code
"Text": "John Doe hat einen Kontakt in der Gruppe" Kontaktaustausch "in Datennutzdaten freigegeben. Sie sollten den Parameter" Text "anstelle der Parameter" Text "oder" Nachricht "für die Nachrichtenbeschreibung oder was auch immer verwenden möchte Text verwenden.

onMessageReceived ()

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.e(TAG, "From: " + remoteMessage.getData().toString());

        if (remoteMessage == null)
            return;

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
           /* Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());*/
            Log.e(TAG, "Data Payload: " + remoteMessage);

            try {

                Map<String, String> params = remoteMessage.getData();
                JSONObject json = new JSONObject(params);
                Log.e("JSON_OBJECT", json.toString());


                Log.e(TAG, "onMessageReceived: " + json.toString());

                handleDataMessage(json);
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }

2

Rufen Sie dies einfach in der onCreate-Methode Ihrer MainActivity auf:

if (getIntent().getExtras() != null) {
           // Call your NotificationActivity here..
            Intent intent = new Intent(MainActivity.this, NotificationActivity.class);
            startActivity(intent);
        }

Wenn ich von mainActivity aus navigiere, wie funktioniert die Rückkehr zu einer bestimmten Aktivität?
Mac_Play

2

nach der lösung von t3h exi möchte ich den sauberen code hier posten. Fügen Sie es einfach in MyFirebaseMessagingService ein und alles funktioniert einwandfrei, wenn sich die App im Hintergrundmodus befindet. Sie müssen mindestens com.google.firebase kompilieren: firebase-messaging: 10.2.1

 @Override
public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }



           onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}

Ich versuche, Ihre Lösung zu implementieren, aber die handleIntent () -Methode ist in meiner SDK-Version (SDK 27) endgültig, sodass ich sie in meinem Dienst nicht überschreiben kann ...
matdev

Ja, aber das ist nicht meine Schuld oder ein Grund, -1 zu geben !!! Sehr arrogant. Es funktioniert bis Firebase 11.4.2, dann hat Google es geändert (diese Methode wurde endgültig). Jetzt müssen Sie Ihre eigene Lösung mit Benachrichtigung programmieren.
Frank

Ich habe keine -1 gegeben, sondern eine +1!
Matdev

Sie retten meinen Job: P
amitabha2715

2

Versuche dies:

public void handleIntent(Intent intent) {
    try {
        if (intent.getExtras() != null) {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");
            for (String key : intent.getExtras().keySet()) {
            builder.addData(key, intent.getExtras().get(key).toString());
        }
            onMessageReceived(builder.build());
        } else {
            super.handleIntent(intent);
        }
    } catch (Exception e) {
        super.handleIntent(intent);
    }
}

handleIntent wird in Firebase nicht mehr verwendet: 11.8.0 und höher.
Shihab Uddin

1

Der Punkt, der hervorgehoben werden sollte, ist, dass Sie nur Datennachricht - Datenschlüssel verwenden müssen Datennachricht ( , um den onMessageReceived-Handler auch dann aufzurufen, wenn sich die App im Hintergrund befindet. Sie sollten keinen anderen Benachrichtigungsnachrichtenschlüssel in Ihrer Nutzlast haben, da sonst der Handler nicht ausgelöst wird, wenn sich die App im Hintergrund befindet.

Es wird hier erwähnt (aber in der FCM-Dokumentation nicht so hervorgehoben):

https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

Verwenden Sie Ihren App-Server und die FCM-Server-API: Legen Sie nur den Datenschlüssel fest . Kann entweder zusammenklappbar oder nicht zusammenklappbar sein.


1

Das Backend, mit dem ich arbeite, verwendet Benachrichtigungsnachrichten und keine Datennachrichten. Nachdem ich alle Antworten gelesen hatte, versuchte ich, die Extras aus dem Bündel der Absichten abzurufen, die für die gestartete Aktivität gelten. Unabhängig davon, von welchen Schlüsseln ich abrufen wollte getIntent().getExtras();, war der Wert immer null.

Endlich habe ich jedoch eine Möglichkeit gefunden, Daten mithilfe von Benachrichtigungsnachrichten zu senden und aus der Absicht abzurufen.

Der Schlüssel hier ist das Hinzufügen der Datennutzdaten zur Benachrichtigungsnachricht.

Beispiel:

{
    "data": {
        "message": "message_body",
        "title": "message_title"
    },
    "notification": {
        "body": "test body",
        "title": "test title"
    },
    "to": "E4An.."
}

Nachdem Sie dies getan haben, können Sie Ihre Informationen folgendermaßen abrufen:

intent.getExtras().getString("title") wird sein message_title

und intent.getExtras().getString("message") wird seinmessage_body

Referenz


1

Wenn Ihr Problem mit der Anzeige von Big Image zusammenhängt, dh wenn Sie eine Push-Benachrichtigung mit einem Bild von der Firebase-Konsole senden und das Bild nur angezeigt wird, wenn die App im Vordergrund steht. Die Lösung für dieses Problem besteht darin, eine Push-Nachricht nur mit Datenfeld zu senden. Etwas wie das:

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

Sie haben vor "AnotherActivity" das Komma verloren. Mein Android vibriert, aber es wird wirklich nichts angezeigt (kein Text, kein Bild, kein Push).
Jekaby

1

Wenn eine Nachricht empfangen wird und sich Ihre App im Hintergrund befindet, wird die Benachrichtigung an die Extras der Hauptaktivität gesendet.

Sie können den zusätzlichen Wert in der Funktion oncreate () oder onresume () der Hauptaktivität überprüfen.

Sie können nach Feldern wie Daten, Tabelle usw. suchen (das in der Benachrichtigung angegebene).

Zum Beispiel habe ich mit Daten als Schlüssel gesendet

public void onResume(){
    super.onResume();
    if (getIntent().getStringExtra("data")!=null){
            fromnotification=true;
            Intent i = new Intent(MainActivity.this, Activity2.class);
            i.putExtra("notification","notification");
            startActivity(i);
        }

}

0

Ich hatte dieses Problem (App möchte beim Klicken auf eine Benachrichtigung nicht geöffnet werden, wenn sich die App im Hintergrund befindet oder geschlossen ist), und das Problem war click_actionim Benachrichtigungstext ungültig . Versuchen Sie, es zu entfernen oder in etwas Gültiges zu ändern.


0

Ich hatte das gleiche Problem und beschäftigte mich noch mehr damit. Wenn sich die App im Hintergrund befindet, wird eine Benachrichtigungsnachricht an die Taskleiste gesendet, ABER eine Datennachricht wird an onMessageReceived()
Siehe https://firebase.google.com/docs/cloud-messaging/downstream#monitor-token-generation_3
und gesendet https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java

Um sicherzustellen, dass die von Ihnen gesendete Nachricht in den Dokumenten lautet: " Verwenden Sie Ihren App-Server und die FCM-Server-API: Legen Sie nur den Datenschlüssel fest. Kann entweder reduzierbar oder nicht reduzierbar sein. "
Siehe https://firebase.google.com/ docs / cloud-messaging / concept-options # notifications_and_data_messages


0

Es gibt zwei Arten von Nachrichten: Benachrichtigungsnachrichten und Datennachrichten. Wenn Sie nur eine Datennachricht senden, ist dies ohne Benachrichtigungsobjekt in Ihrer Nachrichtenzeichenfolge. Es wird aufgerufen, wenn Ihre App im Hintergrund ist.


0

Überprüfen Sie die Antwort von @ Mahesh Kavathiya. Für meinen Fall hat der Servercode nur so:

{
"notification": {
  "body": "here is body",
  "title": "Title",
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

Sie müssen wechseln zu:

{
 "data": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
"notification": {
  "body": "here is body",
  "title": "Title"
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

Wenn die App im Hintergrund angezeigt wird, erhält die zusätzliche Standardabsicht für Aktivitäten "Daten".

Viel Glück!


-1

Überschreiben Sie einfach die OnCreate-Methode von FirebaseMessagingService. Es wird aufgerufen, wenn sich Ihre App im Hintergrund befindet:

public override void OnCreate()
{
    // your code
    base.OnCreate();
}

Diese Antwort könnte nützlicher sein, wenn Sie eine Erklärung hinzufügen und auf eine Dokumentation verweisen könnten. Können Sie uns bitte sagen, wie dies helfen soll?
Kilokahn

@kilokahn Kannst du mir erklären, was du nicht verstehst? Die angegebene Methode muss in den Code eingefügt werden, der Teil der Frage ist und die Frage vollständig beantwortet. Der Code ist für Xamarin, aber Sie können einfach in Java konvertieren.
Renzo Ciot

AFAIK In der offiziellen Dokumentation ( firebase.google.com/docs/cloud-messaging/android/client ) wird nicht über das Überschreiben von OnCreate in einem Dienst gesprochen, der FirebaseMessagingService erweitert. Wenn Sie Zugriff auf eine entsprechende Dokumentation haben, können Sie möglicherweise einen Link freigeben. Aus Ihrer Antwort geht auch nicht hervor, wie das Überschreiben von onCreate das Problem löst, dass onMessageReceived beim Klicken auf die Benachrichtigung nicht aufgerufen wird - daher die Anforderung weiterer Informationen.
Kilokahn

In der Dokumentation wird die Überschreibung der OnCreate-Methode nicht erwähnt, sie funktioniert jedoch, weil ich sie in der Produktion verwende. Der Code, den Sie in die onMessageReceived-Methode einfügen möchten und der offensichtlich dazu dient, einige Hintergrundoperationen auszuführen, kann in OnCreate ausgeführt werden.
Renzo Ciot

In diesem Fall kann es hilfreicher sein, auf die Tatsache einzugehen, dass es irgendwie für Sie funktioniert hat, als nur die Lösung aufzulisten. Außerdem wird undokumentiertes Verhalten wahrscheinlich willkürlich aufhören, mit Updates zu arbeiten, und jemand, der sie verwendet, muss darauf vorbereitet sein, seinen Code zu überarbeiten, wenn dies der Fall ist. Dieser Haftungsausschluss muss
eingefügt werden

-1

Es gibt zwei Arten von Firebase- Push-Benachrichtigungen:

1- Benachrichtigungsnachricht (Meldung anzeigen) -> - 1.1 Wenn Sie diese Variante auswählen, erstellt das Betriebssystem selbst eine Benachrichtigung, wenn sich die App im Hintergrund befindet, und leitet die Daten in der intent. Dann ist es Sache des Kunden, mit diesen Daten umzugehen.

- 1.2 Wenn sich die App im Vordergrund befindet, wird die Benachrichtigung, über callback-functiondie FirebaseMessagingServicesie empfangen wird, im und es ist Sache des Kunden, sie zu bearbeiten.

2- Datennachrichten (bis zu 4k Daten) -> Diese Nachrichten werden verwendet, um nur Daten (stillschweigend) an den Client zu senden, und es ist Sache des Clients, diese für beide Fälle Hintergrund / Vordergrund über die Rückruffunktion in zu verarbeiten FirebaseMessagingService

Dies ist gemäß den offiziellen Dokumenten: https://firebase.google.com/docs/cloud-messaging/concept-options

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.