Firebase FCM通知click_action有效内容

我试图打开一个特定的活动,当用户点击通知,当应用程序在后台。 从文档,我已经得到了click_action必须被添加到有效载荷和应用程序中的意图filter来处理它。 但是,如何通过Firebase控制台在Firebase通知中添加click_action? 我也对任何其他工作开放。 提前致谢。

如果您的应用在后台,Firebase将不会触发onMessageReceived()。 为什么…..? 我不知道。 在这种情况下,我没有看到实施FirebaseMessagingService的意义。

根据文档,如果你想处理后台消息到达,你必须发送“click_action”与您的消息。 但是,只有通过Firebase API从Firebase控制台发送消息才是不可能的。 这意味着你将不得不build立自己的“控制台”,以使营销人员能够使用它。 所以,这使得Firebase控制台也相当无用!

这个新工具背后有一个非常好的,有希望的想法,但是执行得很糟糕。

我想我们将不得不等待新版本和改进/修复!

据我所知,在这一点上是不可能在控制台中设置click_action。

虽然不是如何获得在控制台中设置的click_action的严格答案,但可以使用curl作为替代:

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

这是testingclick_action映射的简单方法。 它需要一个像FCM文档中指定的意图filter:

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

这属于解决方法类别,也包含一些额外的信息:

由于通知根据应用程序的状态(前台/后台/未启动)进行了不同的处理,所以我已经看到了实现助手类的最佳方式,其中根据通知消息中发送的自定义数据启动所选活动。

  • 当应用程序在前台使用onMessageReceived中的助手类
  • 当应用程序在后台使用辅助类来处理主要活动的onNewIntent意图(检查特定的自定义数据)
  • 当应用程序没有运行时,使用帮助程序类来处理主要活动的onCreate中的意图(为意图调用getIntent)。

这样您就不需要特定的click_action或intentfilter。 你也可以只写一次代码,并且可以合理地轻松地开始任何活动。

所以最小的自定义数据看起来像这样:

 Key: run_activity Value: com.mypackage.myactivity 

和处理它的代码:

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

这是最后两种情况的代码,startSelectedActivity也会从onMessageReceived(第一种情况)调用。

限制是所有的意图额外的数据是string,所以你可能需要在活动本身以某种方式处理。 此外,这是简化,你可能不会改变前景上的应用程序上的活动/视图,而不会警告你的用户。

您可以在扩展FirebaseMessagingService的服务中的onMessageReceived()中处理您的消息的所有操作。 为了做到这一点,您必须发送一个包含排他性数据的消息,例如使用Chrome中的高级REST客户端 。 然后,您使用“原始标题”发送POST到https://fcm.googleapis.com/fcm/send

Content-Type:application / json授权:key = YOUR_PERSONAL_FIREBASE_WEB_API_KEY

并在“原始有效载荷”字段中的json消息。

警告,如果在你的json中有字段“通知”,即使有数据字段,在onMessageReceived()的后台应用程序中也不会收到你的消息! 例如,这样做,消息工作只是如果应用程序在前台:

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

为了在onMessageReceived()的所有情况下接收你的消息,只需从你的json中删除“notification”字段!

例:

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

并在您的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"); } } } } 

请享用 !

好吧,从firebase文档中可以明显看出,当应用程序处于后台时, onMessageReceived将不起作用。

当你的应用程序在后台,并点击你的通知,你的默认启动器将启动。 要启动所需的活动,您需要在通知有效内容中指定click_action

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

并在你的android.manifest文件

在注册活动的位置添加以下代码

  <activity android:name="your activity name"> <intent-filter> <action android:name="your activity name" /> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> 

如果您的应用在后台,Firebase将不会触发onMessageReceived()。 当应用程序处于前台时,onMessageReceived()被调用。 当应用程序处于后台时,只有在https://fcm.googleapis.com/fcm/send主体仅包含数据有效内容的情况下,才会调用onMessageReceived()方法。在这里,我刚创build了一个方法来构build自定义通知,你所需要的活动; 并在onMessageRecevied()中调用此方法。

在PostMan中:

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

标题:授权:密钥=您的密钥

身体— >>

 { "data" : { "Nick" : "Mario", "Room" : "PoSDenmark", }, "to" : "xxxxxxxxx" } 

在你的应用程序。

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

当数据有效载荷到达手机,然后onMessageReceived()方法将被称为..在该方法,我只是做了一个自定义通知。 这将工作,即使你的应用程序是背景或前景。

更新:

因此,为了validation,目前无法通过Firebase控制台设置click_action参数。


所以我一直试图在Firebase通知控制台中做到这一点,没有运气。 由于我似乎无法find将click_action值放置在控制台中的任何地方,我主要做了什么来testing这是在通知(高级选项>自定义数据)中添加一个自定义键/值对:

 Key: click_action Value: <your_preferred_value> 

然后尝试在onMessageReceived()调用RemoteMessage.getNotification()。getClickAction()来查看它是否正在检索正确的值,但始终返回null 。 所以接下来我尝试调用RemoteMessage.getData()。get(<specified_key>) ,并能够检索我添加的值。

注意 :我不完全确定这是否可以用作解决方法,或者是否违背了最佳做法。 我build议使用您自己的应用程序服务器,但是您的post是特定于Firebase控制台的。

客户端应用程序和通知的行为方式仍然取决于您如何编程。 这样说,我认为你可以使用上面的解决方法,使用从getData()检索的值,然后通知调用这个或那个。 希望这有助于某种方式。 干杯! :d

现在可以在Firebase控制台中设置click_action。 你只要去通知,发送消息高级选项,那里你将有两个键和值的领域。 在第一个字段中放置click_action,然后在第二个字段中放置一些代表该操作值的文本。 而且你在你的Manifest中添加intent-filter,给他和你在console中写的相同的值。 这就是真正的click_action的模拟。

我正在寻找这个Firebase是,从谷歌云消息推动通知发展的基础,所以我们可以使用gcm教程,function和实施在firebase,我使用gcm推送通知函数function解决这个click_action问题我使用gcm函数**

'notificationclick'

**尝试这个保存urlclick_action在variablesurl这是在server-worker.js

 var url = ""; messaging.setBackgroundMessageHandler(function(payload) { console.log('[firebase-messaging-sw.js] Received background message ', payload); // Customize notification here url = payload.data.click_action; const notificationTitle = payload.data.title; const notificationOptions = { body: payload.data.body , icon: 'firebase-logo.png' }; return self.registration.showNotification(notificationTitle, notificationOptions); }); //i got this in google cloud messaging push notification self.addEventListener('notificationclick', function (event) { event.notification.close(); var clickResponsePromise = Promise.resolve(); clickResponsePromise = clients.openWindow(url); event.waitUntil(Promise.all([clickResponsePromise, self.analytics.trackEvent('notification-click')])); });