android - 负载和通知如何在 Firestore 消息传递中工作

标签 android firebase push-notification firebase-cloud-messaging

我正在使用 Firestore 制作消息传递应用程序,我想在发送新消息时发送通知。为此,我正在使用 FCM。

现在我声明了 2 个有效载荷:一个通知有效载荷和一个数据有效载荷。当用户发送一条消息时,如果应用程序在后台,收件人会收到 2 条通知,如果应用程序在前台,则收到一条通知。如果我删除通知负载,无论应用程序是在前台还是后台,收件人都会收到一条通知。

我想要发生的是,当应用程序处于后台或前台时,用户只会收到一个通知,而如果应用程序处于与发件人的聊天 Activity 中,则不会收到任何通知。我的理解是,当我同时声明通知和数据有效负载时,这应该是默认行为。

Handle notification messages in a backgrounded app

When your app is in the background, Android directs notification messages to the system tray. A user tap on the notification opens the app launcher by default.

This includes messages that contain both notification and data payload (and all messages sent from the Notifications console). In these cases, the notification is delivered to the device's system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.

有人可以帮忙吗?我读过thisthis但它似乎对我不起作用所以也许还有其他我不知道的东西这是我的 list 条目

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

最佳答案

如果你想避免显示通知,你应该在你的 FirebaseMessagingService 上控制它.您的情况看起来是您的应用程序在特定 Activity 中打开。

如果你想在应用程序不在前台时避免通知,那么你应该从服务中检查 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" />到你的 list 。

以防您只想在特定 Activity 中避免使用它。然后你需要找出一种方法来跟踪该 Activity 的生命周期。使用 SharedPreferences , 一个 static变量,你可以在这个 post 中看到多个例子.

关于android - 负载和通知如何在 Firestore 消息传递中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50624486/

相关文章:

Android NavigationView onDestroy 未调用

Android Studio ClassCastException : com. worklight.wlclient.WLPersistentCookieStore

node.js - 使用带有 GET 的查询字符串在本地测试 Firebase HTTP Cloud 函数

php - 如何使用 v1 API 将 FCM 通知发送到特定设备 token 列表

events - grails 2.3事件推送插件

java - Android 可滚动 TextView 边框

android - 为什么 ion-infinite-scroll 在 Android 中不断调用滚动?

firebase - Firestore.settings() 要求它的第一个参数是对象类型,但它是一个自定义对象

firebase - 保护 Firebase 数据免遭授权用户更新自己的数据

android - 当应用程序处于后台时如何在android中获取推送通知?