我正在使用Firestore创建一个消息传递应用,我希望在发送新消息时发送通知。为此,我使用FCM。
现在我宣布2个有效载荷:通知有效载荷和数据有效载荷。当用户发送消息时,如果应用程序在后台,则收件人会收到2个通知,如果应用程序位于前台,则会收到一个通知。如果我删除通知有效负载,则收件人会收到一个通知,无论该应用是在前台还是后台。
我想要发生的是,当应用在后台或前台时,用户只收到一个通知,如果应用与发件人进行聊天活动,则只收到一个通知。我的理解是,当我声明通知和数据有效负载时,这应该是默认行为。
处理后台应用程序中的通知消息
当您的应用在后台时,Android会将通知消息定向到系统托盘。用户点按通知会默认打开应用启动器。
这包括包含通知和数据有效负载的消息(以及从Notifications控制台发送的所有消息)。在这些情况下,通知会传递到设备的系统托盘,并且数据有效负载将在启动器活动的附加内容中传送。
有人可以帮忙吗?我已阅读http://localhost:8100/build/vendor.js:15472:42和this但它似乎并不适合我,所以也许还有其他我不知道的是我的清单条目
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());
}
}
这是我的消息服务,我现在发送非常基本的通知
{{1}}
答案 0 :(得分:2)
如果您想避免显示通知,则应在FirebaseMessagingService
上对其进行控制。您的条件似乎是您的应用程序在特定活动中处于打开状态。
如果您想在应用程序不在Foreground中时避免通知,那么您应该从服务中检查ActivityManager。您可以使用此方法:
public boolean isForeground(String myPackage) {
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> runningTaskInfo = manager.getRunningTasks(1);
ComponentName componentInfo = runningTaskInfo.get(0).topActivity;
return componentInfo.getPackageName().equals(myPackage);
}
同时将<uses-permission android:name="android.permission. REAL_GET_TASKS" />
添加到您的清单。
如果您想在特定活动中避免它。然后,您需要找出一种方法来跟踪该活动的生命周期。使用SharedPreferences
,static
变量...您可以在此post
希望它能帮到你!
答案 1 :(得分:1)
根据您的用例,我认为您需要与您的FCM消息服务通信聊天活动的状态,并决定是否根据该状态提交通知。然后,您只能发送带有效负载的数据部分。
您可以尝试在FCM服务中设置广播接收器,并从聊天活动生命周期事件中广播意图,以通知服务是否应生成通知。
在您的留言服务中:
private boolean chatActive = false;
private String senderID;
@Override
public void onCreate() {
super.onCreate();
LocalBroadcastManager.getInstance(this).registerReceiver(chatReceiver,new IntentFilter("com.mypackage.CHAT_LIFECYCLE_EVENT"));
}
@Override
public void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(chatReceiver);
super.onDestroy();
}
private BroadcastReceiver chatReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
chatActive = intent.getBooleanExtra("active",false);
senderID = intent.getStringExtra("sender");
}
};
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Check for whether chat is active with sender
if(!(chatActive && remoteMessage.getData().get("USER_NAME").equals(senderID)){
//sendNotification
}
}
然后,在您的聊天活动中,您可以在生命周期事件期间发送广播。
@Override
protected void onPause() {
super.onPause();
Intent startNotificationIntent = new Intent();
startNotificationIntent.setAction("com.mypackage.CHAT_LIFECYCLE_EVENT");
startNotificationIntent.putExtra("active",false);
LocalBroadcastManager.getInstance(this).sendBroadcast(startNotificationIntent);
}
@Override
protected void onResume() {
super.onResume();
Intent stopNotificationIntent = new Intent();
stopNotificationIntent.setAction("com.mypackage.CHAT_LIFECYCLE_EVENT");
stopNotificationIntent.putExtra("active",true);
stopNotificationIntent.putExtra("sender",someSenderVariable);
LocalBroadcastManager.getInstance(this).sendBroadcast(stopNotificationIntent);
}