it-swarm.com.de

Firebase (FCM): Öffnen Sie die Aktivität und übergeben Sie die Daten beim Klicken der Benachrichtigung. Android

Die Verwendung von Firebase-Benachrichtigungen und -Daten sollte klar umsetzbar sein. Ich lese viele Antworten, kann aber nicht dazu führen, dass es funktioniert. Hier sind meine Schritte:

1.) Ich übermittle Benachrichtigungen und Daten an Android in PHP und es scheint gut zu sein:

$msg = array
    (
         "body" => $body,
         "title" => $title,
         "sound" => "mySound"
    );

    $data = array
    (

         "user_id" => $res_id,
         "date" => $date,
         "hal_id" => $hal_id,
         "M_view" => $M_view
    );

    $fields = array
    (
        'registration_ids' => $registrationIds,
        'notification' => $msg,
        'data' => $data
    );



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

2.) Wenn Benachrichtigungen und Daten in Android empfangen werden, werden Benachrichtigungen angezeigt. Wenn ich auf diese Benachrichtigung klicke, öffnet sich die App. Ich kann jedoch nicht herausfinden, wie die Daten behandelt werden, wenn die App geöffnet wird. Es gibt einige Unterschiede, wenn sich die App im Vordergrund und im Hintergrund befindet. Der Code, den ich jetzt habe, ist folgender: 

public class MyFirebaseMessagingService extends FirebaseMessagingService {

private static final String TAG = "MyFirebaseMsgService";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

    String user_id = "0";
    String date = "0";
    String cal_id = "0";
    String M_view = "0";

    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        user_id = remoteMessage.getData().get("user_id");
        date = remoteMessage.getData().get("date");
        hal_id = remoteMessage.getData().get("hal_id");
        M_view = remoteMessage.getData().get("M_view");
    }

    //Calling method to generate notification
    sendNotification(remoteMessage.getNotification().getBody(), user_id, date, hal_id, M_view);
}

private void sendNotification(String messageBody, String user_id, String date, String hal_id, String M_view) {
    Intent intent = new Intent(this, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

    intent.putExtra("fcm_notification", "Y");
    intent.putExtra("user_id", user_id);
    intent.putExtra("date", date);
    intent.putExtra("hal_id", hal_id);
    intent.putExtra("M_view", M_view);
    int uniqueInt = (int) (System.currentTimeMillis() & 0xff);
    PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), uniqueInt, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
    notificationBuilder.setSmallIcon(R.drawable.ic_launcher)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

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

3.) Wenn ich den obigen Code verwende und auf alle Benachrichtigungen klicke, wird die App im Hintergrund geöffnet. Wenn die App im Vordergrund und dann beim Benachrichtigungsklick auf klicken, wird die Benachrichtigung einfach abgewiesen. Ich möchte jedoch Daten erhalten und bestimmte Aktivitäten in beiden Szenarien (Hintergrund und Vordergrund) öffnen. Ich habe in MainActivity den folgenden Code, aber ich kann keine Daten abrufen. fcm_notification, date, hal_id gibt null zurück.

public class MainActivity extends Activity {
 UserFunctions userFunctions;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
    Intent intent_o = getIntent();
}

@Override
protected void onResume() {
    super.onResume();
    userFunctions = new UserFunctions();
    if(userFunctions.isUserLoggedIn(getApplicationContext())){
        Intent intent_o = getIntent();
        String fcm_notification = intent_o.getStringExtra("fcm_notification") ;
        String user_id = intent_o.getStringExtra("user_id");
        String date = intent_o.getStringExtra("date");
        String hal_id = intent_o.getStringExtra("hal_id");
        String M_view = intent_o.getStringExtra("M_view");
        Intent intent = new Intent(this, JobList.class);

        // THIS RETURNS NULL, user_id = null
        System.out.print("FCM" + user_id);
        startActivity(intent);
        finish();
    }else{
        // user is not logged in show login screen
        Intent login = new Intent(this, LoginActivity.class);
        startActivity(login);
        // Closing dashboard screen
        finish();
    }
}}

WENN jeder direkt etwas dazu sagen oder raten kann, wie ich Daten in MainActivity.Java von Firebase abrufen kann (in jedem Szenario (Vordergrund oder Hintergrund)), wäre das fantastisch. 

33
Vaidas

Nachdem Sie alle Antworten und Blogs ausprobiert hatten, kam die Lösung. Wenn jemand etwas braucht, benutzen Sie bitte dieses Video als Referenz

https://www.youtube.com/watch?v=hi8IPLNq59o

Zusätzlich zum Video, um Absichten hinzuzufügen, tun Sie dies in MyFirebaseMessagingService:

public class MyFirebaseMessagingService extends FirebaseMessagingService {

private static final String TAG = "MyFirebaseMsgService";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

    String user_id = "0";
    String date = "0";
    String hal_id = "0";
    String M_view = "0";

    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        user_id = remoteMessage.getData().get("user_id");
        date = remoteMessage.getData().get("date");
        cal_id = remoteMessage.getData().get("hal_id");
        M_view = remoteMessage.getData().get("M_view");
    }

    String click_action = remoteMessage.getNotification().getClickAction();

    //Calling method to generate notification
    sendNotification(remoteMessage.getNotification().getBody(), remoteMessage.getNotification().getTitle(), user_id, date, hal_id, M_view, click_action);
}

private void sendNotification(String messageBody, String messageTitle, String user_id, String date, String hal_id, String M_view, String click_action) {
    Intent intent = new Intent(click_action);
    intent.putExtra("user_id", user_id);
    intent.putExtra("date", date);
    intent.putExtra("hal_id", hal_id);
    intent.putExtra("M_view", M_view);

    PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent,
            PendingIntent.FLAG_ONE_SHOT);

    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
    notificationBuilder.setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(messageTitle)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

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

fügen Sie dies in der neuen NotificationReceive-Aktivität in onCreate oder onResume hinzu

    notification_Y_N = (TextView) findViewById(R.id.notification_Y_N);
    user_id_text = (TextView) findViewById(R.id.user_id_text);

    Intent intent_o = getIntent();
    String user_id = intent_o.getStringExtra("user_id");
    String date = intent_o.getStringExtra("date");
    String hal_id = intent_o.getStringExtra("hal_id");
    String M_view = intent_o.getStringExtra("M_view");

    notification_Y_N.setText(date);
    user_id_text.setText(hal_id);
20
Vaidas

Als Erstes füge ich die Details hinzu, die in den Dokumenten docs handling messages aufgeführt sind.

In der Zusammenfassung unter der Zeile Both wird angezeigt, dass sich die Payload in der onMessageReceived() befindet, wenn sich die App auf Vordergrund befindet.

Um die Aktivität von onMessageReceived() zu öffnen, sollten Sie prüfen, ob sich die benötigten Daten in der Nutzlast befinden. Wenn dies der Fall ist, rufen Sie Ihre spezifische Aktivität auf, und geben Sie alle weiteren erforderlichen Informationen mit Absicht ab.

Wenn sich die App in background befindet, wird in den Dokumenten darauf hingewiesen, dass die Benachrichtigung vom Android-Taskleiste empfangen wird und dass die data-Nutzlast von den Extras der Absicht abgerufen werden kann.

Fügen Sie einfach die Details aus meiner Antwort hier hinzu, die die docs-Anweisung und einen Link zu einem Beispiel enthält:

Benachrichtigungsnachrichten in einer Hintergrundanwendung bearbeiten

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

Dies umfasst Nachrichten, die sowohl als auch Benachrichtigung und Datennutzlast enthalten (und alle von der Benachrichtigungskonsole gesendeten Nachrichten). In diesen Fällen wird die Benachrichtigung an die Systemablage des Geräts übermittelt, und die Datennutzlast wird in den Extras der Absicht Ihrer Starteraktivität geliefert.

Ich denke, diese answer von @ArthurThompson erklärt es sehr gut:

Wenn Sie eine Benachrichtigungsnachricht mit einer Datennutzlast senden (Benachrichtigung und Daten) und die App im Hintergrund ist, können Sie die Daten von den Extras der Absicht abrufen, die als Ergebnis des Benutzerabbruchs auf die Benachrichtigung gestartet wird.

Aus dem FCM-Beispiel , das die MainActivity startet, wenn die Benachrichtigung angezapft wird:

if (getIntent().getExtras() != null) {
    for (String key : getIntent().getExtras().keySet()) {
        String value = getIntent().getExtras().getString(key);
        Log.d(TAG, "Key: " + key + " Value: " + value);
    }
}
31
AL.

Um die onMessageReceived()-Methode aufzurufen, müssen Sie eine andere Methode zum Senden von Benachrichtigungen verwenden (z. B. Erstellen einer Web-API zum Senden von Benachrichtigungen). Dann verwenden, 

Entfernen Sie die Benachrichtigungsnutzdaten aus Ihren FCM-Nachrichten, damit die Datennutzdaten an die onMessageReceived()-Methode gesendet werden.

Wenn sich Ihre App im Hintergrund befindet, wird die Datennutzlast nur dann an die onMessageReceived-Methode übermittelt, wenn keine Benachrichtigungsnutzlast vorhanden ist.

Wenn beide Payloads vorhanden sind, verarbeitet das System automatisch die Benachrichtigungsteil (Taskleiste) und Ihre App erhält die Datennutzdaten in die Extras der Absicht der Starter-Aktivität (nachdem der Benutzer auf die Benachrichtigung geklickt hat).

Weitere Informationen finden Sie unter den folgenden Links:

1
Ashu

Sie müssen sendNotification und onMessageReceived nicht selbst implementieren.

Wenn du sendest:

$data = array
(
    "user_id" => $res_id
    //whatever fields you want to include
);

$msg = array
(
     "body" => $body,
     "title" => $title,
     "data" => $data
     // more fields
);

Android-Seite (auf Ihrer MainACtivity:

private void handleIntent(Intent intent) {
    String user_id= intent.getStringExtra("user_id");
    if(user_id!= null)
        Log.d(TAG, user_id);
}

und natürlich:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    handleIntent(intent);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    handleIntent(getIntent());
}

alle Felder, die Sie in data eingeben, werden an Ihre Absicht extra gesendet.

0
Ohad Cohen