如何在后台和前台处理 Firebase 通知?
Posted
技术标签:
【中文标题】如何在后台和前台处理 Firebase 通知?【英文标题】:How to handle firebase notification on background as well as foreground? 【发布时间】:2017-03-16 07:19:09 【问题描述】:我想在后台和前台处理 firebase 通知消息。我将发送一条消息,其中包含来自开发人员的 youtube 链接,当用户点击通知栏时,它必须引导用户打开链接。有谁知道它是怎么做的吗?
public void onMessageReceived(RemoteMessage remoteMessage)
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// [END_EXCLUDE]
// TODO(developer): Handle FCM messages here.
// Not getting messages here? See why this may be:
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0)
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null)
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
接下来要做什么来实现我的目标?在此先感谢:)
【问题讨论】:
发布的代码只是示例中的代码。所以我假设你已经通过了它们。有什么令人困惑的地方吗?你也浏览过文档吗?现在,这就像一个给我代码问题。 试试我的解决方案?我已经试过了。它有效***.com/questions/48897883/… 【参考方案1】:您应该在 FCM 消息中发送数据负载。无论您的应用程序处于前台还是后台,都会在消息方法中接收数据有效负载。处理那里的动作。比如通过始终读取数据负载来显示通知,或者如果您想在应用打开或在前台显示警报对话框。
这是一个示例负载:
"to": "registration_id_or_topic",
"data":
"message": "This is a Firebase Cloud Messaging Topic Message!",
"youtubeURL": "https://youtu.be/A1SDBIViRtE"
然后在你的 onMessageReceived 中:
public void onMessageReceived(RemoteMessage remoteMessage)
if (remoteMessage.getData().size() > 0)
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
Map<String, String> receivedMap = remoteMessage.getData();
String youtubeURL = receivedMap.get("youtubeURL");
showNotificationWithURLAction(youtubeURL);
.....
您可以通过谷歌搜索轻松实现 showNotificationWithURLAction(...) 方法。一个样本是here
【讨论】:
如何在有效载荷中发送链接以及如何在用户点击时处理该链接?请帮帮我 请参阅下面@Lindani Masinga 的答案。我也会更新我的答案 要从控制台发送数据有效载荷,请参阅@Drake29a 的以下答案【参考方案2】:这可能与this question 重复。不要在推送消息正文中发送“通知”。
所以基本上,我将推送通知请求的正文从:
"data":
"type" : "mytype"
,
"notification":
"title": "My Title",
"body": "My Notification Message"
,
"to": "/topics/all"
收件人:
"data":
"type" : "mytype",
"title": "My Title",
"body": "My Notification Message"
,
"to": "/topics/all"
现在我的应用即使在后台也每次都会调用 onMessageReceived(),我只是更改了方法以在推送数据中使用获得的通知标题和消息。
【讨论】:
嗨,我的应用没有在后台调用 onMessageReceived()。 谢谢!这是最重要和可接受的信息。从 8 小时开始,我一直在不停地挣扎,终于!正如你所说..它在两种情况下都有效 Alvin,后台应用程序是什么意思,我们应该在应用程序被杀死时收到通知,不仅在后台或前台。 @SagarPanwala 在后台,我的意思是当应用程序当前对用户不可见时 正是 Alvin,但我们都需要在应用被终止时收到通知【参考方案3】:当您的应用终止或后台从不触发 onMessageReceive
你该怎么办?
当推送发送时只添加下面示例中的数据项; 你可以使用邮递员
首先需要这个网址:https://fcm.googleapis.com/fcm/send 发送时可以选择 发布
在你应该添加这样的标题之后:
内容类型:application/json
授权:key="你的服务器密钥"
"to": "/topics/yourTopics",
"data":
"title": "BlaBla",
"body":"BlaBla"
如何处理;
class PushService : FirebaseMessagingService()
override fun onMessageReceived(remoteMessage: RemoteMessage?)
for (i in remoteMessage!!.data.keys)
//Your maps here you can do something..
val contentIntent = PendingIntent.getActivity(this,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
// Your notification set here!!
val b = NotificationCompat.Builder(this, "1")
val n = b.setTicker(remoteMessage!!.data["title"])
.setWhen(0)
.setAutoCancel(true)
.setContentTitle(remoteMessage.data["title"])
.setContentText(remoteMessage.data["body"])
.setShowWhen(true)
.setContentIntent(contentIntent)
.setSound(uri)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher))
.setStyle(NotificationCompat.BigTextStyle().bigText(remoteMessage.data["body"]))
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
b.setSmallIcon(R.drawable.ic_push_notification_transparent)
b.color = ContextCompat.getColor(this, R.color.colorAccent)
else
b.setSmallIcon(R.mipmap.ic_launcher)
val notificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
val channel = NotificationChannel("1",
"ic_notification",
NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
if (notificationManager != null)
notificationManager.cancel(1)
notificationManager.notify(1, n.build())
【讨论】:
【参考方案4】:android 系统将始终处理有效负载中通知字段内的消息。如果您希望您的应用处理通知,则需要将 YouTube 链接放在有效负载的该数据字段中。
"data" :
"link" : "www.youtube.com"
此通知在应用程序上作为 RemoteMessage 接收。使用 remoteMessage.getData() 获取 youtube 链接。
见https://firebase.google.com/docs/cloud-messaging/concept-options#messages-with-both-notification-and-data-payloads
【讨论】:
嗨,我的应用没有在后台调用 onMessageReceived()。【参考方案5】:如果您想将用户重定向到应用中的内容而不是使用 deepLink, 以下是点击通知时如何打开链接:
Intent notificationIntent = new Intent(Intent.ACTION_VIEW);
notificationIntent.setData(Uri.parse(remoteMessage.getData().getString("url"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
// Resources r = getResources();
Notification notification = new NotificationCompat.Builder(context)
.setTicker("yortext")
.setSmallIcon(android.R.drawable.ic_menu_report_image)
.setContentTitle("title")
.setContentText("content")
.setContentIntent(pendingIntent)
.build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
要将有效负载发送到 Firebase 控制台,创建新消息,在这里您将拥有高级选项,您可以在其中将数据放在键/值对中,放入 网址如下图所示。
【讨论】:
Drake 在 fb 上接受我的好友请求我想对 firebase @Drake29a 提出更多疑问 在这里提问,fb 上没有好友请求。【参考方案6】:这是一个用 nodejs 编写的适用于所有类型条件处理的工作示例 Foreground、BackGround、APP Killed 这将适用于所有三种情况类型
let message =
"data":
"callerName": "callerName",
"notifyType": "notifyType",
"channelName": "channelName",
"tragetuid": "tragetuid",
"msg": "msg"
,
token: "cq4KgPelQ_ukmAL1NmNs0l:APA91bG0l2uS1djSsD181cgtgFSd8......",
;
let response = await admin.messaging().send(message).catch((error) =>
console.log('Error sending message:', error);
);
if (!response)
ctx.status = 404;
ctx.body = "Error";
else
ctx.status = 200;
ctx.body =
response, message
;
所以基本上我们需要使用类型 data 而不是 notification 在 OnReceived() 函数中获取 FCM 消息
"data":
"callerName": "callerName",
"notifyType": "notifyType",
"channelName": "channelName",
"tragetuid": "tragetuid",
"msg": "msg"
,
token: "cq4KgPelQ_ukmAL1NmNs0l:APA91bG0l2uS1djSsD181cgtgFSd8......",
【讨论】:
以上是关于如何在后台和前台处理 Firebase 通知?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Firebase前台推送通知未显示但后台正在运行