wake-up-neo.com

Firebase FCM-Benachrichtigungen click_action payload

Ich versuche, eine bestimmte Aktivität zu öffnen, wenn der Benutzer auf die Benachrichtigung klickt, während sich die App im Hintergrund befindet. Aus den Dokumenten habe ich erfahren, dass click_action in die Payload eingefügt werden muss und ein Intent-Filter in der App, um damit umzugehen. Aber wie fügt man click_action über die Firebase-Konsole in die Firebase-Benachrichtigungen ein? Ich bin auch offen für andere Work Around. Danke im Voraus.

45
Hariharan B

Befindet sich Ihre App im Hintergrund, löst Firebase onMessageReceived () nicht aus. Warum.....? Ich habe keine Ahnung. In dieser Situation sehe ich keinen Grund, FirebaseMessagingService zu implementieren.

Laut docs müssen Sie "click_action" mit Ihrer Nachricht senden, wenn Sie den Eingang der Hintergrundnachricht verarbeiten möchten. Das Senden von Nachrichten über die Firebase-Konsole ist jedoch nur über die Firebase-API möglich. Dies bedeutet, dass Sie Ihre eigene "Konsole" erstellen müssen, damit Marketingmitarbeiter sie verwenden können. Das macht die Firebase-Konsole also auch ziemlich nutzlos!

Hinter diesem neuen Tool steckt eine wirklich gute, vielversprechende Idee, die aber schlecht umgesetzt wurde.

Ich nehme an, wir müssen auf neue Versionen und Verbesserungen/Korrekturen warten!

51
Bozic Nebojsa

Soweit ich das beurteilen kann, ist es derzeit nicht möglich, click_action in der Konsole einzustellen.

Obwohl dies keine strikte Antwort darauf ist, wie Sie die click_action-Gruppe in der Konsole erhalten, können Sie alternativ auch curl verwenden:

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

Dies ist eine einfache Möglichkeit, die click_action-Zuordnung zu testen. Es ist ein Absichtsfilter erforderlich, wie er in den FCM-Dokumenten angegeben ist:

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

Dabei werden auch Themen genutzt, um das Publikum anzusprechen. Damit dies funktioniert, müssen Sie ein Thema namens "Nachrichten" abonnieren.

FirebaseMessaging.getInstance().subscribeToTopic("news");

Obwohl es einige Stunden dauert, bis ein neu erstelltes Thema in der Konsole angezeigt wird, können Sie über die FCM-APIs weiterhin Nachrichten an die Konsole senden.

Beachten Sie auch, dass dies nur funktioniert, wenn sich die App im Hintergrund befindet. Wenn es im Vordergrund ist, müssen Sie eine Erweiterung von FirebaseMessagingService implementieren. In der onMessageReceived-Methode müssen Sie manuell zu Ihrem click_action-Ziel navigieren:

    @Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    //This will give you the topic string from curl request (/topics/news)
    Log.d(TAG, "From: " + remoteMessage.getFrom());
    //This will give you the Text property in the curl request(Sample Message): 
    Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
    //This is where you get your click_action 
    Log.d(TAG, "Notification Click Action: " + remoteMessage.getNotification().getClickAction());
    //put code here to navigate based on click_action
}

Wie bereits erwähnt, kann ich derzeit nicht über die Konsole auf Eigenschaften für Benachrichtigungsnutzdaten zugreifen, aber ich dachte, diese Problemumgehung könnte hilfreich sein.

49
maddesa

Sie können alle Ihre Aktionen in Abhängigkeit von Ihrer Nachricht in onMessageReceived () in Ihrem Dienst behandeln, der FirebaseMessagingService erweitert. Dazu müssen Sie eine Nachricht senden, die ausschließlich Daten enthält, beispielsweise Advanced REST client in Chrome . Anschließend senden Sie ein POST to https://fcm.googleapis.com/fcm/send unter Verwendung von "Raw Headern":

Inhaltstyp: application/json Autorisierung: key = YOUR_PERSONAL_FIREBASE_WEB_API_KEY

Und eine json Nachricht im Feld "Raw payload".

Warnung: Wenn in Ihrem json das Feld "Benachrichtigung" vorhanden ist, wird Ihre Nachricht bei der App im Hintergrund in onMessageReceived () niemals empfangen, selbst wenn ein Datenfeld vorhanden ist! Wenn Sie dies tun, funktioniert die Nachricht beispielsweise nur, wenn die App im Vordergrund ist:

{
    "condition": " 'Symulti' in topics || 'SymultiLite' in topics",
    "priority" : "normal",
    "time_to_live" : 0,
    "notification" : {
        "body" : "new Symulti update !",
        "title" : "new Symulti update !",
        "icon" : "ic_notif_symulti"
    },
    "data" : {
        "id" : 1,
        "text" : "new Symulti update !"
    }
}

Um Ihre Nachricht in allen Fällen in onMessageReceived () zu erhalten, entfernen Sie einfach das Feld "notification" von Ihrem json!

Beispiel:

{
    "condition": " 'Symulti' in topics || 'SymultiLite' in topics",
    "priority" : "normal",
    "time_to_live" : 0,,
    "data" : {
        "id" : 1,
        "text" : "new Symulti update !",
        "link" : "href://www.symulti.com"
    }
}

und in Ihrem FirebaseMessagingService:

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
      String message = "";
      obj = remoteMessage.getData().get("text");
      if (obj != null) {
        try {
          message = obj.toString();
        } catch (Exception e) {
          message = "";
          e.printStackTrace();
        }
      }

      String link = "";
      obj = remoteMessage.getData().get("link");
      if (obj != null) {
        try {
          link = (String) obj;
        } catch (Exception e) {
          link = "";
          e.printStackTrace();
        }
      }

      Intent intent;
      PendingIntent pendingIntent;
      if (link.equals("")) { // Simply run your activity
        intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      } else { // open a link
        String url = "";
        if (!link.equals("")) {
          intent = new Intent(Intent.ACTION_VIEW);
          intent.setData(Uri.parse(link));
          intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        }
      }
      pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
          PendingIntent.FLAG_ONE_SHOT);


      NotificationCompat.Builder notificationBuilder = null;

      try {
        notificationBuilder = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_notif_symulti)          // don't need to pass icon with your message if it's already in your app !
            .setContentTitle(URLDecoder.decode(getString(R.string.app_name), "UTF-8"))
            .setContentText(URLDecoder.decode(message, "UTF-8"))
            .setAutoCancel(true)
            .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
            .setContentIntent(pendingIntent);
        } catch (UnsupportedEncodingException e) {
          e.printStackTrace();
        }

        if (notificationBuilder != null) {
          NotificationManager notificationManager =
              (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
          notificationManager.notify(id, notificationBuilder.build());
        } else {
          Log.d(TAG, "error NotificationManager");
        }
      }
    }
}

Genießen !

25
Maxime Ancelin

Dies fällt in die Kategorie der Problemumgehung, die auch einige zusätzliche Informationen enthält:

Da die Benachrichtigungen je nach Status der App unterschiedlich behandelt werden (Vordergrund/Hintergrund/Nicht gestartet), habe ich die beste Möglichkeit gesehen, eine Hilfsklasse zu implementieren, bei der die ausgewählte Aktivität basierend auf den in der Benachrichtigungsnachricht gesendeten benutzerdefinierten Daten gestartet wird.

  • wenn die App im Vordergrund ist, verwenden Sie die Hilfsklasse in onMessageReceived
  • wenn sich die App im Hintergrund befindet, verwenden Sie die Hilfsklasse für die Verarbeitung der Absicht in der Hauptaktivität onNewIntent (überprüfen Sie, ob bestimmte benutzerdefinierte Daten vorhanden sind).
  • wenn die App nicht ausgeführt wird, verwenden Sie die Hilfsklasse zum Behandeln der Absicht in der onCreate-Hauptaktivität (rufen Sie getIntent für die Absicht auf).

Auf diese Weise benötigen Sie keinen spezifischen click_action- oder intent-Filter. Außerdem schreiben Sie den Code nur einmal und können jede Aktivität relativ einfach starten.

Die minimalen benutzerdefinierten Daten würden also ungefähr so ​​aussehen:

Key: run_activity
Value: com.mypackage.myactivity

Und der Code für den Umgang damit:

if (intent.hasExtra("run_activity")) {
    handleFirebaseNotificationIntent(intent);
}


private void handleFirebaseNotificationIntent(Intent intent){
    String className = intent.getStringExtra("run_activity");
    startSelectedActivity(className, intent.getExtras());
}

private void startSelectedActivity(String className, Bundle extras){
    Class cls;
    try {
        cls = Class.forName(className);
    }catch(ClassNotFoundException e){
        ...
    }
    Intent i = new Intent(context, cls);

    if (i != null) {
        i.putExtras(extras);
        this.startActivity(i);
    } 
}

Dies ist der Code für die letzten beiden Fälle. StartSelectedActivity wird auch von onMessageReceived (erster Fall) aufgerufen.

Die Einschränkung besteht darin, dass alle Daten in den Intent-Extras Zeichenfolgen sind. Daher müssen Sie diese möglicherweise in der eigentlichen Aktivität behandeln. Dies ist auch vereinfacht, wahrscheinlich können Sie die Aktivität/Ansicht in einer im Vordergrund befindlichen App nicht ändern, ohne Ihren Benutzer zu warnen.

16
diidu

Aus Firebase-Dokumenten geht hervor, dass Ihr onMessageReceived nicht funktioniert, wenn sich die App im Hintergrund befindet.

Wenn sich Ihre App im Hintergrund befindet und Sie auf Ihre Benachrichtigung klicken, wird Ihr Standard-Launcher gestartet. Um Ihre gewünschte Aktivität zu starten, müssen Sie click_action in Ihrer Benachrichtigungsnutzlast.

$noti = array
    (
    'icon' => 'new',
    'title' => 'title',
    'body' => 'new msg',
    'click_action' => 'your activity name comes here'
); 

Und in deinem Android.manifest Datei

Fügen Sie den folgenden Code hinzu, in dem Sie Ihre Aktivität registriert haben

     <activity
                Android:name="your activity name">
                <intent-filter>
                    <action Android:name="your activity name" />
                   <category Android:name="Android.intent.category.DEFAULT"/>
               </intent-filter>
   </activity>
13
gagan bhutani

Befindet sich Ihre App im Hintergrund, löst Firebase onMessageReceived () nicht aus. onMessageReceived () wird aufgerufen, wenn sich die App im Vordergrund befindet. Wenn sich die App im Hintergrund befindet, wird die Methode onMessageReceived () nur aufgerufen, wenn der Body von https://fcm.googleapis.com/fcm/send nur Nutzdaten enthält. Hier habe ich gerade eine Methode erstellt um eine benutzerdefinierte Benachrichtigung mit der Absicht zu erstellen, dass Sie Ihre gewünschte Aktivität ausführen. und rief diese Methode in onMessageRecevied () auf.

Im PostMan:

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

header: Authorization: key = ur key

körper --- >>

{  "data" : {
      "Nick" : "Mario",
      "Room" : "PoSDenmark",

    },

  "to" : "xxxxxxxxx"

}

in Ihrer Bewerbung.

class MyFirebaseMessagingService  extends FirebaseMessagingService {

 public void onMessageReceived(RemoteMessage remoteMessage) {
       if (remoteMessage.getData().size() > 0) {
           sendNotification("ur message body") ;
        }
    }
private void sendNotification(String messageBody) {
        Intent intent = new Intent(this, Main2Activity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_ic_notification)
                .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());
    }

 }

wenn die Datennutzdaten auf dem Mobiltelefon eingehen, wird die Methode onMessageReceived () aufgerufen. Innerhalb dieser Methode habe ich gerade eine benutzerdefinierte Benachrichtigung erstellt. Dies funktioniert auch dann, wenn Ihre App im Hintergrund oder im Vordergrund ist.

5
chandan raj

Update:

Zur Verifizierung ist es derzeit nicht möglich, den Parameter click_action Über die Firebase-Konsole festzulegen.


Daher habe ich versucht, dies in der Firebase-Benachrichtigungskonsole zu tun, ohne Erfolg. Da ich den Wert click_action Anscheinend nirgends in der Konsole finden kann, habe ich hauptsächlich ein benutzerdefiniertes Schlüssel/Wert-Paar in die Benachrichtigung eingefügt (Erweiterte Optionen> Benutzerdefinierte Daten), um dies zu testen. :

Key: click_action
Value: <your_preferred_value>

dann wurde versucht, RemoteMessage.getNotification (). getClickAction () in onMessageReceived() aufzurufen, um festzustellen, ob der richtige Wert abgerufen wurde, aber es wird immer null zurückgegeben. Als nächstes habe ich versucht, RemoteMessage.getData (). Get (<specific_key>) aufzurufen und konnte den von mir hinzugefügten Wert abrufen.

[~ # ~] Anmerkung [~ # ~] : Ich bin mir nicht ganz sicher, ob das in Ordnung ist, um dieses Problem zu umgehen, oder ob es dagegen ist beste Übung. Ich würde vorschlagen, einen eigenen App-Server zu verwenden, aber Ihr Beitrag ist spezifisch für die Firebase-Konsole.

Das Verhalten der Client-App und der Benachrichtigung hängt weiterhin davon ab, wie Sie sie programmieren. Wenn dies gesagt ist, können Sie das Obige als Problemumgehung verwenden, indem Sie den Wert verwenden, der aus getData() abgerufen wurde, und dann die Benachrichtigung dies oder jenes aufrufen lassen. Hoffe das hilft irgendwie. Prost! : D

3
AL.

Jetzt ist es möglich, click_action in der Firebase-Konsole einzustellen. Gehen Sie einfach zur Option Benachrichtigungen - Nachricht senden - Erweitert und dort haben Sie zwei Felder für Schlüssel und Wert. Im ersten Feld geben Sie click_action und im zweiten Text ein, der den Wert dieser Aktion darstellt. Und Sie fügen Intent-Filter in Ihr Manifest ein und geben ihm den gleichen Wert, den Sie in der Konsole geschrieben haben. Und das ist die Simulation einer echten Klick-Aktion.

1
Atenica