【发布时间】:2018-11-10 11:28:06
【问题描述】:
我正在使用 Firestore 制作消息应用程序,我想在发送新消息时发送通知。为此,我正在使用 FCM。
现在我要声明 2 个有效负载:一个通知有效负载和一个数据有效负载。当用户发送消息时,如果应用程序在后台,收件人会收到 2 条通知,如果应用程序在前台,则收到一条通知。如果我删除通知负载,无论应用程序是在前台还是后台,收件人都会收到一条通知。
我想要发生的是,当应用程序处于后台或前台时,用户只会收到一个通知,而如果应用程序处于与发件人的聊天活动中,则不会收到通知。我的理解是,当我声明通知和数据有效负载时,这应该是默认行为。
在后台应用中处理通知消息
当您的应用处于后台时,Android 会将通知消息定向到系统托盘。默认情况下,用户点击通知会打开应用启动器。
这包括同时包含通知和数据负载的消息(以及从通知控制台发送的所有消息)。在这些情况下,通知会传送到设备的系统托盘,而数据负载会在启动器 Activity 的 Intent 的附加部分中传送。
有人可以帮忙吗?我已阅读 this 和 this 但它似乎对我不起作用,所以也许还有其他我不知道的东西这里是我的清单条目
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
这是我的云功能,包含通知和数据负载
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.notifyNewMessage =
functions.firestore
.document('users/{ID}/contacts/{contactID}/messages/{messageID}')
.onCreate((docSnapshot , context) => {
const message = docSnapshot.data()
const recipientId = message['recipientId']
const senderId = message['sender']
const senderName = message['senderName']
return admin.firestore().doc('users/' + recipientId).get().then(userDoc =>{
const registrationTokens = userDoc.get('registeredToken')
const notificationBody = (message['data_type'] === "TEXT") ?
message['message'] : "You received a new image message."
const payload = {
notification : {
title : senderName + " sent you a message.",
body : notificationBody
},
data : {
TITLE : senderName + " sent you a message.",
BODY : notificationBody,
USER_NAME : senderName,
USER_NUMBER : message['sender'],
CLICK_ACTION : "MessageListActivity",
MESSAGE : message['message'],
}
}
return
admin.messaging().sendToDevice(registrationTokens,payload).then(response
=> {
})
})
})
这是我的消息服务,我现在发送非常基本的通知
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final int NOTIFICATION_MAX_CHARACTERS = 30;
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Map<String, String> data = remoteMessage.getData();
if (data.size() > 0) {
sendNotification(data);
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
}
}
private void sendNotification(Map<String, String> data) {
String author = data.get("USER_NAME");
String title = data.get("TITLE");
String body = data.get("BODY");
String id = data.get("USER_NUMBER");
String message = data.get("MESSAGE");
Intent intent = new Intent(this, MessageListActivity.class);
intent.putExtra(Constants.USER_NAME, author);
intent.putExtra(Constants.USER_NUMBER, id);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Create the pending intent to launch the activity
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
if (message.length() > NOTIFICATION_MAX_CHARACTERS) {
message = message.substring(0, NOTIFICATION_MAX_CHARACTERS) +
"\u2026";
}
Uri defaultSoundUri =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new
NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_email_black_24dp)
.setContentTitle(String.format(getString(R.string.notification_message),
author))
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */,
notificationBuilder.build());
}
}
【问题讨论】:
-
我觉得你的问题和这个stackoverflow.com/a/50338208/4017501很相似
标签: android firebase push-notification firebase-cloud-messaging