Firebase FCM 通知 click_action 有效载荷

我试图打开一个特定的活动时,用户点击通知时,应用程序在后台。从文档中,我得知 click _ action 必须添加到有效负载中,并在 App 中添加一个意图过滤器来处理它。但是,如何通过 Firebase 控制台在 Firebase 通知中添加 click _ action?我也愿意接受其他的工作。提前感谢。

176890 次浏览

更新:

因此,只是为了验证,目前不可能通过 Firebase 控制台设置 click_action参数。


所以我一直尝试在 Firebase 通知控制台中做这件事,但是没有成功。因为我似乎找不到任何地方放置控制台中的 click_action值,我主要做的是测试这一点是添加一个自定义键/值对在通知(前进选项 > 自定义数据) :

Key: click_action
Value: <your_preferred_value>

然后尝试在 onMessageReceived()中调用 GetNotification () . getClickAction ()来查看它是否检索了正确的值,但它总是返回 null。因此,接下来我尝试调用 GetData () . get (<  指定 _ key >),并能够检索我添加的值。

注意 : 我不完全确定这是否可以作为变通方法使用,或者它是否违背了最佳实践。我建议使用你自己的应用服务器,但你的文章是特定的火库控制台。

客户端应用程序和通知的行为方式仍然取决于您如何编程它。既然这样,我认为您可以使用上面的解决方案,使用从 getData()检索到的值,然后让 Notification 调用 this 或 that。希望这能有所帮助。干杯!校对: D

据我所知,此时不可能在控制台中设置 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-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

这还利用主题来设置受众。为了这个工作,你将需要订阅一个主题称为“新闻”。

FirebaseMessaging.getInstance().subscribeToTopic("news");

即使在控制台中查看新创建的主题需要几个小时,您仍然可以通过 FCM apis 向其发送消息。

另外,请记住,这将只有在应用程序在后台工作。如果它在前台,则需要实现 FirebaseMessagingService 的扩展。在 onMessageRecected 方法中,需要手动导航到 click _ action 目标:

    @Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//This will give you the topic string from curl request (/topics/news)
Log.d(TAG, "From: " + remoteMessage.getFrom());
//This will give you the Text property in the curl request(Sample Message):
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//This is where you get your click_action
Log.d(TAG, "Notification Click Action: " + remoteMessage.getNotification().getClickAction());
//put code here to navigate based on click_action
}

如前所述,目前我无法找到通过控制台访问通知有效负载属性的方法,但是我认为这项工作可能会有所帮助。

如果您的应用程序在后台,Firebase 将不会触发 onMessageRecected ()。为什么?我不知道。在这种情况下,我认为实现 FirebaseMessagingService 没有任何意义。

根据文档,如果你想处理背景消息到达,你必须发送‘ click _ action’和你的消息。 但是,如果您只通过 FirebaseAPI 从 Firebase 控制台发送消息,那么这是不可能的。 这意味着你将不得不建立自己的“控制台”,以使营销人员使用它。所以,这使得 Firebase 控制台也相当无用!

这个新工具背后确实有很好的、有前途的想法,但是执行得很糟糕。

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

这属于变通方法的范畴,也包含一些额外的信息:

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

  • 当应用程序处于前台时,使用 onMessageRecected 中的 helper 类
  • 当应用程序处于后台时,使用 helper 类处理 main 活动的 onNewInent 中的意图(检查特定的自定义数据)
  • 当应用程序不运行时,使用 helper 类处理 main 活动的 onCreate 中的意图(为意图调用 getInent)。

这样,您就不需要指定给它的 click _ action 过滤器或意图过滤器。此外,您只需编写一次代码,就可以轻松地启动任何活动。

因此,最小自定义数据应该是这样的:

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 也将从 onMessageRecected (第一种情况)调用。

限制在于意图额外部分中的所有数据都是字符串,因此您可能需要在活动本身中以某种方式处理它。此外,这是简化,你可能不什么改变活动/视图的应用程序,在前台没有警告你的用户。

现在可以在 Firebase 控制台中设置 click _ action。您只需进入“通知-发送消息-高级”选项,就可以看到键和值的两个字段。第一个字段是 click _ action,第二个字段是一些表示该操作值的文本。然后在清单中添加意图过滤器,并给他与在控制台中编写的相同的值。 这就是真实点击动作的模拟。

您可以在扩展 FirebaseMessagingService 的服务中处理 onMessageRecected ()中消息功能中的所有操作。 为此,必须发送一条包含完全数据的消息,例如使用 Chrome 中的高级 REST 客户端。 然后向 https://fcm.googleapis.com/fcm/send发送一个 POST 在「原始标头」中使用:

Content-Type: application/json 内容-类型: application/json 授权: key = YOUR _ Personal _ FIREBASE _ WEB _ API _ KEY

还有“原始有效载荷”的 json 消息。

警告,如果您的 json 中有一个“通知”字段,那么即使有一个数据字段,当 onMessageRecected ()中的应用程序处于后台时,您的消息也永远不会被接收到! 例如,做到这一点,消息工作,只要应用程序在前台:

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

为了在所有情况下接收 onMessageRecected ()中的消息,只需从 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");
}
}
}
}

好好享受吧!

我正在寻找这个 Firebase 是,从 Google云消息传递推送基本通知开发,所以我们可以使用 gcm 教程,功能和实现在 Firebase, 我使用 gcm 推送通知函数来解决这个 click _ action 问题 我使用 gcm 函数 * *

“通知点击”

** 尝试将 url < em > click _ action 保存到变量 < em > url 中,这是在 < strong > 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')]));
});

如果您的应用程序在后台,Firebase 将不会触发 onMessageRecected ()。 当应用程序位于前台时调用 onMessageRecected ()。 当应用程序处于后台时,只有当 https://fcm.googleapis.com/fcm/send的主体只包含数据有效负载时,才会调用 onMessageRecected ()方法。在这里,我只是创建了一个方法来构建自定义通知,目的是让您所需的活动。并在 onMessageRecevied ()中调用此方法。

邮差:

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

Header: Authorization: key = ur key 头: 授权: key = ur key

身体—— >

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


}

when the data payload comes to the mobile,then onMessageReceived() method will be called.. inside that method ,i just made a custom notification. this will work even if ur app is background or foreground.

从 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>

对于 fcm 有对偶的方法 Fcm 消息通知和应用程序通知 首先您的应用程序收件人只有消息通知与身体,标题和您可以添加颜色,振动不工作,声音默认。 在第二,你可以完全控制什么发生时,你收到消息的例子 onMessageReciever(RemoteMessage rMessage){ notification.setContentTitle(rMessage.getData().get("yourKey")); } 您将用(yourKey)接收数据 但不是来自 Fcm 信息 来自 fcm 云函数 警戒

在 Web 中,只需添加您想要打开的 URL:

{
"condition": "'test-topic' in topics || 'test-topic-2' in topics",
"notification": {
"title": "FCM Message with condition and link",
"body": "This is a Firebase Cloud Messaging Topic Message!",
"click_action": "https://yoururl.here"
}
}

一个简单的解决方法是,在 fcm 选项中——添加 /作为链接值,后台通知单击将被重定向到应用程序。

假设我想导航到 www.aaa.com/news/post/41

"click_action":"/news/post/41"添加到通知键中,例如:

"notification":{
"title":"   Greetings",
"body":"This is okay",
"click_action":"/news/post/41"


}

即使在后台也能用。如果你有一个 PWA 应用程序,它也可以工作; 我还没有在 iOS 或本地 Android 应用程序中测试过它。