web-dev-qa-db-de.com

Firebase Expandable Notification Zeigt ein Bild an, wenn sich die App im Hintergrund befindet

Ich implementiere FCM-Benachrichtigungen in Android, aber wie unterscheiden sich Benachrichtigungen je nach App-Status (Hintergrund vs. Vordergrund)?

see notifications image

Ich versende die Benachrichtigung mithilfe der FCM-API mit Postman. Dies ist die Benachrichtigungsstruktur:

{ "notification": {
      "title": "Notification title",
      "body": "Notification message",
      "sound": "default",
      "color": "#53c4bc",
      "click_action": "MY_BOOK",
      "icon": "ic_launcher"
   },
   "data": {
       "main_picture": "URL_OF_THE_IMAGE"  
   },
   "to" : "USER_FCM_TOKEN"
}

Das zu rendernde Bild wird aus data.main_picture übernommen.

Ich habe meine eigene FirebaseMessagingService implementiert, wodurch die Benachrichtigungen perfekt im Vordergrund angezeigt werden. Der Benachrichtigungscode ist der nächste:

NotificationCompat.BigPictureStyle notiStyle = new NotificationCompat.BigPictureStyle();
notiStyle.setSummaryText(messageBody);
notiStyle.bigPicture(picture);

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

NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setLargeIcon(bigIcon)
            .setContentTitle(title)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent)
            .setStyle(notiStyle); code here

NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());

Im Hintergrund wird der Dienst jedoch nicht ausgeführt. Im AndroidManifest.xml werden Firebase-Dienste wie folgt deklariert:

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

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

Mein Problem ist nicht LargeIcon oder SmallIcon, sondern das große Bild.

Danke für deine Unterstützung.

FCM notification messages unterstützt das largeIcon oder das bigPicture nicht.

wenn Sie sie im Hintergrund benötigen, können Sie einen FCM data message verwenden.

Für Datennachrichten wird immer die onMessageReceived(message)-Methode aufgerufen, sodass Sie die message.getData()-Methode verwenden und Ihre benutzerdefinierte Benachrichtigung erstellen können.

Weitere Informationen zu Benachrichtigungsnachrichten und Datenmeldungen finden Sie hier: https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

13
Diego Giorgini

Siehe mein FirebaseMessagingService 

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "FirebaseMessageService";
    Bitmap bitmap;

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // There are two types of messages data messages and notification messages. Data messages are handled
        // here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
        // traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
        // is in the foreground. When the app is in the background an automatically generated notification is displayed.
        // When the user taps on the notification they are returned to the app. Messages containing both notification
        // and data payloads are treated as notification messages. The Firebase console always sends notification
        // messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
        //
        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());
        }

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

        //The message which i send will have keys named [message, image, AnotherActivity] and corresponding values.
        //You can change as per the requirement.

        //message will contain the Push Message
        String message = remoteMessage.getData().get("message");
        //imageUri will contain URL of the image to be displayed with Notification
        String imageUri = remoteMessage.getData().get("image");
        //If the key AnotherActivity has  value as True then when the user taps on notification, in the app AnotherActivity will be opened. 
        //If the key AnotherActivity has  value as False then when the user taps on notification, in the app MainActivity will be opened. 
        String TrueOrFlase = remoteMessage.getData().get("AnotherActivity");

        //To get a Bitmap image from the URL received
        bitmap = getBitmapfromUrl(imageUri);

        sendNotification(message, bitmap, TrueOrFlase);

    }


    /**
     * Create and show a simple notification containing the received FCM message.
     */

    private void sendNotification(String messageBody, Bitmap image, String TrueOrFalse) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.putExtra("AnotherActivity", TrueOrFalse);
        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)
                .setLargeIcon(image)/*Notification icon image*/
                .setSmallIcon(R.drawable.firebase_icon)
                .setContentTitle(messageBody)
                .setStyle(new NotificationCompat.BigPictureStyle()
                        .bigPicture(image))/*Notification with Image*/
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

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

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

    /*
    *To get a Bitmap image from the URL received
    * */
    public Bitmap getBitmapfromUrl(String imageUrl) {
        try {
            URL url = new URL(imageUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap bitmap = BitmapFactory.decodeStream(input);
            return bitmap;

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;

        }
    }
}

VERWEIS HIER

9
Arpit Patel

Wenn Ihr Problem mit der Anzeige von Big Image zusammenhängt, d. H. Wenn Sie Push-Benachrichtigungen mit einem Bild von der Firebase-Konsole senden, wird das Bild nur angezeigt, wenn sich die App im Vordergrund befindet. Die Lösung für dieses Problem ist das Senden einer Push-Nachricht mit nur Datenfeld.

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

Dies löst das Problem definitiv.

3
Arun

Falls einige 2019 hier landen, können Sie einfach ein Bild Feld zum Benachrichtigungsobjekt hinzufügen:

    {
        notification: {
            title: title,
            body: body,
            image: "http://path_to_image"
        },
        data: {
            click_action: "FLUTTER_NOTIFICATION_CLICK",
            your_data: ...,
        },
        token: token
    }

Ich habe es mit Flutter auf Android und ich würde davon ausgehen, dass es auf native Android funktioniert, da beide wahrscheinlich das gleiche native SDK verwenden.

3
gatti

Der Datenschlüssel muss im Push-Benachrichtigungspaket enthalten sein. 

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.

1
Max Droid

Nachrichten, die sowohl Benachrichtigungen als auch Daten enthalten (wie in Ihrem Beispiel mit Postman gesendet), werden von der FCM-Bibliothek automatisch für Endbenutzergeräte angezeigt. Und dies beinhaltet keine (großen) Bilder.

Ich denke, es gibt zwei Möglichkeiten für Sie:

  1. Versuchen Sie, was Rashmi Jain vorgeschlagen hat. Diese Lösung könnte jedoch sofort funktionieren und morgen nicht mehr funktionieren, wenn die Firebase-Bibliothek aktualisiert wird (und damit die Implementierung der Nachrichtenverarbeitung).

  2. Senden Sie eine Datennachricht mit Postman. Sie können das Benachrichtigungsobjekt daher nicht in der JSON füllen, daher könnte es ungefähr so ​​aussehen:

    {
      "message": {
        "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
        "data":{    
          "title" : "Awesome title",
          "body"  : "Your awesome Push notification body",
          "image"  : "your_image_url"
        }
      }
    }
    

Ich würde die zweite Option vorziehen. Viel Glück!

1
Benjamin Menrad

Senden Sie eine Big Picture-Benachrichtigung von der Firebase-Konsole aus: Funktioniert für Hintergrund- und Vordergrund-App

Überschreiben Sie zzm () von FirebaseMessagingService anstelle von onMessageReceived und erstellen Sie hier Ihre benutzerdefinierte Benachrichtigung

@Override
public void zzm(Intent intent) {
    Log.e(TAG, "zzm : " + intent);
    createBigPictureNotification();        
}

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}
0
Rashmi Jain

Update 2019 August.

[ein paar Tage verschwendet, nur weil py die letzten Änderungen für Benachrichtigungen nicht unterstützt]

Fügen Sie einfach image = url in Ihr Benachrichtigungsobjekt ein.

Es funktioniert in Native Android . Fügen Sie einfach image zum Benachrichtigungsobjekt hinzu. Beachten Sie auch, dass in der Bibliothek das Bildfeld Python=) nicht existiert. [Stand: 19. August] https://github.com/firebase/firebase-admin-python =

Ich habe PHP und diese Bibliothek https://github.com/kreait/firebase-php/ verwendet. Es ist super einfach und vor allem funktioniert es für große Bildbenachrichtigungen, wenn App ist im Hintergrund oder wurde getötet.

Code:

<?php

require __DIR__.'/vendor/autoload.php';
require __DIR__.'/simple_html_dom.php';

use Kreait\Firebase;
use Kreait\Firebase\ServiceAccount;
use Kreait\Firebase\Messaging\Notification;
use Kreait\Firebase\Messaging\CloudMessage;

$serviceAccount = ServiceAccount::fromJsonFile('/path/to/cred.json');

$firebase = (new Firebase\Factory())->withServiceAccount($serviceAccount)->create();
$messaging = $firebase->getMessaging();

// this works when app is closed or in bg
$notification = Notification::fromArray([
    'title' => $title,
    'body' => $body,
    'image' => $imageUrl,
]);

// for foreground process 
$data = [
    'image' => $imageUrl,
    'news_id' => $news_id,
];

$topic = 'default_topic1';

$message = CloudMessage::withTarget('topic', $topic)
    ->withNotification($notification) // optional
    ->withData($data);

$messaging->send($message);

print_r($message);
0
user3526

Wenn Sie nur eine Benachrichtigung in einer Taskleiste für Ihre App erwarten, kann die untenstehende Lösung das Problem lösen, bis FCM die richtige Lösung gefunden hat.

  1. entfernen Sie MyFirebaseMessagingService aus dem Manifest.

    <service Android:name=".MyFirebaseMessagingService">   <intent-filter> <action Android:name="com.google.firebase.MESSAGING_EVENT"/>   </intent-filter> </service>
    
  2. MyGcmReceiver Erweitern Sie die GcmReceiver-Klasse und klicken Sie auf die Benachrichtigungslogik.
  3. Fügen Sie MyGcmReceiver im Manifest hinzu

        <receiver
        Android:name=".MyGcmReceiver"
        Android:exported="true"
        Android:permission="com.google.Android.c2dm.permission.SEND">
        <intent-filter>
            <action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
            <category Android:name="package_name" />
        </intent-filter>
    </receiver>
    
  4. cancelAll Benachrichtigungen vor der Benachrichtigung. (Ansonsten auch Firebase, zeigt Benachrichtigung an, wenn sich die App im Hintergrund befindet.)

0
Harsha Vardhan

Mit diesem Restclient-Tool können Sie Nachrichten senden. Mit diesem Tool können Sie auch im Hintergrund und im Vordergrund Nachrichten an die Client-App senden .. Um eine Nachricht mit der API zu senden, können Sie ein Tool mit dem Namen AdvancedREST Client verwenden. und senden Sie eine Nachricht mit den folgenden Parametern.

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: Schlüssel = 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-Nachricht mit API "" AnotherActivity ":" True "}," bis ":" Geräte-ID oder Gerätetoken "}

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.

Und dieses Stück Android-Code // Nachricht enthält die Push-Nachricht

    String message = remoteMessage.getData().get("message1");

    //imageUri will contain URL of the image to be displayed with Notification


    String imageUri = remoteMessage.getData().get("image");

    //If the key AnotherActivity has  value as True then when the user taps on notification, in the app AnotherActivity will be opened.

    //If the key AnotherActivity has  value as False then when the user taps on notification, in the app MainActivity2 will be opened.

    String TrueOrFlase = remoteMessage.getData().get("AnotherActivity");

    //To get a Bitmap image from the URL received

    bitmap = getBitmapfromUrl(imageUri);


    sendNotification(message, bitmap, TrueOrFlase);
0

Wenn Sie eine Push-Benachrichtigung senden, erhalten Sie beispielsweise anstelle einer Benachrichtigung alle erforderlichen Daten

{
   "data": {
       "main_picture": "URL_OF_THE_IMAGE",
       "title": "Notification title",
      "click_action": "MY_BOOK", 
      "color": "#53c4bc", 
   },
   "to" : "USER_FCM_TOKEN"
}

benachrichtigungsobjekt entfernen und alle Werte aus dem Datenobjekt abrufen.

Ich hoffe, dass es für Sie funktioniert.

0
Hardik Kotadiya