Firebase FCM通知click_action有效内容
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Firebase FCM通知click_action有效内容相关的知识,希望对你有一定的参考价值。
当用户在后台点击通知时,我正在尝试打开特定活动。从Docs中,我已经知道必须在有效负载中添加click_action,并在App中使用intent过滤来处理它。但是,如何通过Firebase控制台在Firebase通知中添加click_action?我也对任何其他工作开放。提前致谢。
如果您的应用处于后台,Firebase将不会触发onMessageReceived()。为什么.....?我不知道。在这种情况下,我认为实施FirebaseMessagingService没有任何意义。
根据文档,如果您要处理后台消息到达,您必须发送带有消息的“click_action”。但是,如果您仅通过Firebase API从Firebase控制台发送消息,则无法进行此操作。这意味着您必须构建自己的“控制台”才能使营销人员使用它。所以,这使得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"}}"
这是测试click_action映射的简便方法。它需要像FCM文档中指定的那样的intent过滤器:
<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
您可以在扩展FirebaseMessagingService的服务中的onMessageReceived()中处理消息功能的所有操作。为此,您必须使用例如Advanced REST client in Chrome发送仅包含数据的消息。然后使用“原始标题”向https://fcm.googleapis.com/fcm/send发送POST:
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中删除“通知”字段!
例:
{
"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");
}
}
}
}
请享用 !
这属于变通方法类别,也包含一些额外信息:
由于通知的处理方式不同,具体取决于应用程序的状态(前景/后台/未启动),我已经看到了实现辅助类的最佳方法,其中根据通知消息中发送的自定义数据启动所选活动。
- 当应用程序在前台时,使用onMessageReceived中的帮助程序类
- 当应用程序在后台时,使用辅助类来处理主活动的onNewIntent中的意图(检查特定的自定义数据)
- 当应用程序未运行时,使用辅助类来处理主活动的onCreate中的意图(为intent调用getIntent)。
这样您就不需要特定于它的click_action或intent过滤器。您也只需编写一次代码,就可以轻松地开始任何活动。
所以最小的自定义数据看起来像这样:
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(第一种情况)调用。
限制是intent附加内容中的所有数据都是字符串,因此您可能需要在活动本身中以某种方式处理它。此外,这是简化的,您可能无法在不警告用户的情况下更改前台应用上的活动/视图。
从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()。当app在前台时调用onMessageReceived()。当app在后台时,只有当https://fcm.googleapis.com/fcm/send的主体仅包含数据有效负载时才会调用onMessageReceived()方法。在这里,我刚刚创建了一个方法来构建自定义通知,意图具有您所需的活动。并在onMessageRecevied()中调用此方法。
在PostMan中:
:https://fcm.googleapis.com/fcm/send
header:授权:key = ur key
身体--- >>
{ "data" : {
"Nick" : "Mario",
"Room" : "PoSDenmark",
},
"to" : "xxxxxxxxx"
}
在你的申请中。
class MyFirebaseMessagingService extends FirebaseMessagingService {
public void onMessage以上是关于Firebase FCM通知click_action有效内容的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 FCM(Firebase 云消息传递)制作紧凑通知?