web-dev-qa-db-fra.com

Console Firebase: Comment spécifier click_action pour les notifications

J'ai implémenté Firebase et testé les notifications Firebase . Lorsque l'application est au premier plan, je n'ai pas de problèmes, j'ai implémenté un service qui étend FirebaseMessagingService et gère le message et les données dans onMessageReceived

J'ai des problèmes lorsque l'application est en arrière-plan, j'aimerais envoyer une notification qui ouvre une activité spécifique et fait ce que je prévois de faire, pas seulement ouvrir l'application.

J'ai effectué les tâches décrites dans le guide Firebase, mais je ne suis pas en mesure de démarrer l'activité spécifique.

Voici le manifeste:

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

Et voici la console Firebase. Que dois-je écrire dans ces champs pour ouvrir mon "BasicNotificationActivity"?

 Firebase console

14
Alex

Voici une copie de cette question: Notifications FCM Firebase click_action payload

Mais la réponse acceptée par l’auteur de cette question indique simplement que ce n’est pas possible avec Firebase Console, mais c’est - avec une solution de contournement simple. Cette réponse de diidu à la même question explique la solution que j'utiliserais.

METTRE À JOUR:
Pour élaborer sa réponse: 

Ajoutez une classe d'assistance (ou implémentez la méthode startActivity() d'une manière ou d'une autre): 

public class ClickActionHelper {
    public static void startActivity(String className, Bundle extras, Context context){
        Class cls;
        try {
            cls = Class.forName(className);
        }catch(ClassNotFoundException e){
            //means you made a wrong input in firebase console
        }
        Intent i = new Intent(context, cls);
        i.putExtras(extras);
        context.startActivity(i);
    }
}

Dans l'activité de lancement de votre application, appelez un mehtod pour vérifier les nouvelles intentions dans onCreate() et onNewIntent() (onNewIntent() n'est appelé qu'à la place de onCreate() si Activity est lancé avec un indicateur à sommet unique):

@Override
protected void onCreate(Bundle bundle) {
    [...]
    checkIntent(getIntent());
 }

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    [...]
    checkIntent(intent);
}

public void checkIntent(Intent intent) {
       if (intent.hasExtra("click_action")) {
        ClickActionHelper.startActivity(intent.getStringExtra("click_action"), intent.getExtras(), this);
       }
}

Et dans onMessageReceived():

 public void onMessageReceived(RemoteMessage remoteMessage) {
     Map<String, String> data = remoteMessage.getData();        
     if (data.containsKey("click_action")) {
         ClickActionHelper.startActivity(data.get("click_action"), null, this);
     }
 }

Pour envoyer une notification avec la console Firebase, définissez une paire clé-valeur en tant que données personnalisées, comme suit:

Key: click_action
Value: <fully qualified classname of your activity>

Désormais, lorsqu'une notification est reçue et que l'utilisateur clique dessus, votre activité sera ouverte. Si votre application est au premier plan, elle passera immédiatement à l'activité. Il serait probablement judicieux de demander à l'utilisateur s'il souhaite accéder à cette activité ou non (en affichant une boîte de dialogue dans onMessageReceived()).

21
Micha F.

J'ai utilisé la méthode handleIntent(Intent intent) pour gérer intent et passer à cet écran particulier. Voici mon code qui fonctionne parfaitement même lorsque l'application est en arrière-plan:

FCMMessagingService.Java qui extends FCMMessagingService

@Override
    public void handleIntent(Intent intent) {
        super.handleIntent(intent);

     Intent i = null;
     String value_action = "";

      if (intent.getExtras() != null) {
          if (key.equals("click_action")) {
                value_action = intent.getExtras().getString(key);
            }

          i = new Intent(FCMMessagingService.this, MainActivity.class);
          i.putExtra("notificationFlag", value_action);
          i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

      }
     PendingIntent pendingIntent = PendingIntent.getActivity(this, notifCount, i, PendingIntent.FLAG_ONE_SHOT);
        final int icon = R.mipmap.logo;
    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);

    Notification notification;
    notification = notificationBuilder.setSmallIcon(icon).setTicker(title)
            .setAutoCancel(true)
            .setContentTitle(title)
            .setContentText(body)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent)
            .setSmallIcon(R.mipmap.notification_icon)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), icon))
            .build();


    notificationBuilder.setContentTitle(title);
    notificationBuilder.setContentText(body);
    notificationBuilder.setAutoCancel(true);
    notificationBuilder.setSound(defaultSoundUri);
    notificationBuilder.setContentIntent(pendingIntent);
    notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(getResources(), icon));
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
        notificationBuilder.setSmallIcon(R.mipmap.logo);
    } else {
        notificationBuilder.setSmallIcon(R.mipmap.logo);
    }

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(notifCount, notification);

}
1
R G

J'ai aussi le problème, comme toi, mais je n'ai pas de bonne réponse. C'est ce que je sais,

  1. onNewIntent 

cette méthode de substitution ne fonctionne pas lorsque l'application est en arrière-plan, car l'action par défaut estAndroid.intent.action.MAIN 

  1. Console Firebase

la console Firebase n’est pas assez puissante pour gérer click_action cela signifie que l’action de clic ne peut pas atteindre l’application lorsque celle-ci est en arrière-plan.

  1. CURL

Curl travaille dans l'arrière-plan de l'application, mais pas au premier plan, je ne peux pas trouver.

curl --header "Authorization: key=<Colud_Messaging_Server_Key_here>" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  -d "{\"to\":\"dwdfosu6SDs:APA91bFWxZZB2f8AOgP9MG504cy5AhFECHGbYFfIzVixoAfy-ErT0NYQrREg150CbKYBtk3Ywpu7WQuWsQhk-VmoOe-0iDK3ZgaFZNvYxDuixZB8zQp0zydoXhyrMosi5C4eyBb7Ai1z\",\"notification\": {\"title\": \"Click Action Message\",\"text\": \"Sample message\",\"click_action\":\"noti\",\"ticket_download\":\"noti\"}}"

Ajouter un manifeste

<activity
   Android:name=".activity.TicketDownload"
   Android:exported="true">
   <intent-filter>
      <action Android:name="noti" />
      <category Android:name="Android.intent.category.DEFAULT" />
   </intent-filter>
</activity>

remarque: cloud_messaging_server_key est le paramètre de localisation> cloudmessaging

s'il y a quelque chose de nouveau, merci de me le faire savoir.

0
Nyan Lin Tun

Cette question a 2 ans. Mais cela reste pertinent . Voici comment vous pouvez le faire avec la console firebase (sans `click_action).

Lorsque votre application est en arrière-plan, onMessageReceived ne sera pas appelé. Toutefois, lorsque vous recevez une notification alors que votre application est en arrière-plan, vous obtenez une Intent ainsi que les données personnalisées que vous spécifiez dans la console Firebase.

Ainsi, lorsque l'utilisateur appuie sur, la notification the intent sera alors exécutée pour ouvrir votre activité de lanceur. Vous pouvez vérifier les données par getIntent().hasExtra("key") dans votre activité de lancement. Où "key" est la clé que vous spécifiez dans la console.

Vérifiez si vous avez ce "key", vous pouvez alors créer une autre Intent et appeler startActivity

Voici une implémentation de la mienne,

Sur ma SplashActivity> OnCreate (Cette méthode est préférable si vous avez un écran de démarrage comme activité du programme de lancement):

if (getIntent().hasExtra("key")){

      Intent intent = new Intent(this, TargetActivity.class);
      startActivity(intent);
      finish();

} else {
      startActivity(new Intent(this, MainActivity.class));
      finish();
}

Cela va juste commencer la TargetActivity. Vous pouvez ajouter n'importe quelle fonctionnalité à ceci selon votre souhait :)

0
Ali