63 votes

Firebase (FCM): activité ouverte et transmission de données en cliquant sur la notification. Android

Il devrait être clair de mise en œuvre de la façon de travailler avec Firebase de notification et de données. J'ai lu beaucoup de réponses mais n'arrive pas à le faire fonctionner. voici mes étapes:

1.) Je suis de passage de notification et de données pour android en PHP et il semble aller pour le mieux:

$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.) lors de la notification et de la réception des données dans Android, il affiche une notification. Lorsque je clique sur cette notification, il ouvre l'app. Mais je n'arrive pas à comprendre la façon de traiter les données lorsque l'application est ouverte. Il y a quelques différences lorsque l'application est en premier plan et d'arrière-plan. Le code que j'ai maintenant est la suivante:

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.) Lorsque j'utilise le code ci-dessus et lorsque je clique sur la notification de tout ce qu'il fait, il ouvre l'application si dans le fond. Si l'application en premier plan puis sur notification sur elle rejette tout simplement de notification. Cependant, je souhaite recevoir des données et d'ouvrir Activité spécifique dans les deux scénarios (l'avant et l'arrière). J'ai dans MainActivity le code suivant, mais je ne suis pas en mesure d'obtenir les données. fcm_notification, date, hal_id renvoie la valeur null.

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

SI quelqu'un peut direct ou de conseils comment puis-je récupérer des données dans MainActivity.java de Firebase que soit le scénario (au premier plan ou arrière-plan), ce serait merveilleux.

74voto

AL. Points 21726

Donc, tout d'abord, je vais mettre dans les détails mentionnés dans la gestion des Messages docs.

Dans le sommaire en vertu de la Deux ligne, il montre que lorsque l'application est sur le premier plan, la charge utile sera gérée dans votre onMessageReceived().

Afin d'ouvrir l'activité à partir de onMessageReceived(), vous devez vérifier si les données dont vous avez besoin est dans la charge utile, si c'est le cas, appelez votre activité puis passer tous les autres détails dont vous avez besoin via intention.

Maintenant, si l'application est en arrière-plan, il est mentionné dans les docs que la notification est reçue par le système Android bac et que l' data de la charge utile peut être récupéré à partir de la extras de l'intention.

Simplement en ajoutant dans les détails de ma réponse ici qui assez bien donne juste les docs déclaration et un lien vers un exemple:

Gérer les messages de notification dans un backgrounded app

Lorsque votre application est en arrière-plan, Android dirige les messages de notification de la barre d'état système. Un utilisateur d'appuyer sur la notification s'ouvre l'app launcher par défaut.

Cela inclut les messages qui contiennent à la fois de notification et les données de charge utile (et tous les messages envoyés par les Notifications de la console). Dans ces cas, l'avis est transmis à l'appareil de la barre d'état système, et les données de charge utile est livré dans les extras de l'intention de votre lanceur d'Activité.

Je pense que cette réponse par @ArthurThompson l'explique très bien:

Lorsque vous envoyez un message de notification avec une charge utile de données (notification et de données) et que l'application est en arrière-plan, vous pouvez récupérer les données depuis les extras de l'intention qui est lancé comme un résultat de l'utilisateur en tapant sur la notification.

De la FCM de l'échantillon , qui lance le MainActivity lorsque la notification est exploité:

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

36voto

Vaidas Points 532

Après avoir essayé toutes les réponses et les blogs sont venus avec la solution. si quelqu'un a besoin, veuillez utiliser cette vidéo comme référence

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

EN PLUS de la vidéo à ajouter à l'intention de 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());
}}
 

et dans la nouvelle activité NotificationReceive dans onCreate ou onResume, ajoutez ceci

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

4voto

Ashu Points 95

Pour appeler l' onMessageReceived() méthode, vous devrez utiliser une autre méthode pour envoyer des notifications (comme la création d'une API Web pour envoyer des notifications). Puis en l'utilisant,

supprimer la notification de la charge utile de votre FCM messages afin d'avoir la charge utile de données livrés à l' onMessageReceived() méthode.

Lorsque votre application est en arrière-plan, les données de la charge utile est livré à l' onMessageReceived méthode uniquement si il n'y a pas de notification de la charge utile.

Dans le cas où les deux charges utiles existent ensuite, le système gère automatiquement la la notification de la partie (barre d'état système) et votre application obtient les données de charge utile dans les extras de l'intention de lanceur d'Activité (après à l'utilisateur d'appuyer sur la notification).

Pour plus d'informations, veuillez consulter les liens suivants:

2voto

Ohad Cohen Points 384

Vous n'avez pas besoin de mettre en œuvre sendNotification et onMessageReceived vous-même.

Lors de l'envoi:

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

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

côté android (sur votre MainACtivity :

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

et bien sur:

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

quels que soient les champs que vous avez mis en data seront envoyés à votre intention extra

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X