java 我编写的一个方法不自觉地运行了不止一次

oiopk7p5  于 2023-06-28  发布在  Java
关注(0)|答案(2)|浏览(110)

通过云功能,我可以从一个设备向接收设备发送通知。但是,我在聊天屏幕上发送的第一条消息之后的通知将与之前的所有通知一起再次发送。第一消息中的一个通知、第二消息中的两个通知和第三消息中的3个通知以这种方式继续。通常它只需要为每个消息发送一个通知。我已经试了几个小时了,我找不到错误的来源。
在这里,在每次在firabase数据库中的Notifications/collection下添加新通知文件时触发的事件中,我将收件人id设置为Topic。由于我已经为收件人订阅了此主题,因此通知只会发送给他。我认为这里没有问题。
云函数服务中的index.js

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

exports.androidPushNotification = functions.firestore.document("Notifications/{docId}").onCreate(
    (snapshot, context) => {
        admin.messaging().sendToTopic(
            snapshot.data().userid,
            {
                notification: {
                    title: snapshot.data().title,
                    body: snapshot.data().body
                }
            }
        )
    }
);

这是我的ChatDetailActivity类。当发送消息时,我向Notifications/目录添加一个文件,以便触发上述通知发送事件。我将title、senirid、name和profilepic信息添加到这个文件的title元素中(我找不到任何其他方法,这是我想到的)。使用分割管理,我在显示通知的同时解析信息,并像这样显示通知。在body元素中,有用户发送的消息信息。我认为问题出在这里,因为当在firestore数据库中添加通知时,以前消息的信息再次添加,并为旧消息触发上面的onCreate事件。这听起来像是一个简单的运行时错误。但我解决不了问题

private void sendNotification(String recieverid, String body) {
        FirebaseFirestore firestore = FirebaseFirestore.getInstance();
        firestore.collection("users").document(mUser.getUid()).addSnapshotListener((value, error) -> {
            String profilepic;
            String name;
            if (value != null){
                name = value.getString("name");
                profilepic = value.getString("profilepic");
                Map<String, Object> notification = new HashMap<>();
                notification.put("userid", recieverid);
                notification.put("title", "Anonim Chat" + "&data" + senderid + "&data" + name + "&data" + profilepic);
                notification.put("body", name + ": " + body);
                firestore.collection("Notifications").document().set(notification).addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        Log.w("test-message", "onComplete: bildirim başarıyla eklendi gönderildi");
                    }
                }).addOnFailureListener(e -> Log.e("test-message", "onFailure: " + e.getLocalizedMessage()));
            }
        });

下面是FirebaseMessagingService类。我正在解析Cloud Function发送的通知中title对象中的信息,并显示通知。如果有人能帮忙我会很高兴的。我对这个问题很着迷。

public class PushNotificationService extends FirebaseMessagingService {
     
        @Override
        public void onNewToken(@NonNull String token) {
            super.onNewToken(token);
        }
     
        @Override
        public void onMessageReceived(@NonNull RemoteMessage message) {
            super.onMessageReceived(message);
     
            String gelenMesaj = Objects.requireNonNull(message.getNotification()).getTitle();
            assert gelenMesaj != null;
            String[] dizi = gelenMesaj.split("&data", 100);
            Log.w("MESSAGE", "onMessageReceived: SenderID: " + dizi[1]);
     
            String title = dizi[0];
            String senderid = dizi[1];
            String name = dizi[2];
            String profilepic= dizi[3];
            if (!ChatDetailActivity.getNotificationSenderId().equals(senderid)){
                String body = message.getNotification().getBody();
                final String CHANNEL_ID = "HEADS_UP_NOTIFICATIONS";
                NotificationChannel channel = new NotificationChannel(
                        CHANNEL_ID,
                        "MyNotification",
                        NotificationManager.IMPORTANCE_HIGH);
     
                channel.enableLights(false);
                channel.enableVibration(true);
                channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
     
     
                Intent intent = new Intent(getApplicationContext(), ChatDetailActivity.class);
                intent.putExtra("userid", senderid);
                intent.putExtra("name", name);
                intent.putExtra("profilepic", profilepic);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
     
                getSystemService(NotificationManager.class).createNotificationChannel(channel);
                Notification.Builder notification = new Notification.Builder(this, CHANNEL_ID)
                        .setContentTitle(title)
                        .setContentText(body)
                        .setContentIntent(pendingIntent)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setAutoCancel(true);
     
                Log.w("BODY", "onMessageReceived: " + body);
     
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
                    Log.w("NOTIFY", "İzin yok izin istenmeli");
                    return;
                }
                NotificationManagerCompat.from(this).notify(1, notification.build());
            }
        }
    }
2eafrhcq

2eafrhcq1#

TL;DR:您没有告诉Cloud Functions您正在运行异步操作(sendToTopic),这会导致它重试。
云函数应该 * 始终 *:

  • 返回一个值,指示是否成功。任何值都可以,但必须返回一些值。
  • 或者返回一个Promise,当它完成异步操作时进行解析。

由于您没有执行这两项操作,因此Cloud Functions运行时会假设出现错误并重试。

exports.androidPushNotification = functions.firestore.document("Notifications/{docId}").onCreate(
    (snapshot, context) => {
        return admin.messaging().sendToTopic(
            snapshot.data().userid,
            {
                notification: {
                    title: snapshot.data().title,
                    body: snapshot.data().body
                }
            }
        )
    }
);

由于sendToTopic已经返回了一个Promise,因此我们可以将其返回给Cloud Functions以使其正常工作。
也可以参考terminating functions的文档,包括里面的精彩视频系列。

62lalag4

62lalag42#

private void sendNotification(String recieverId, String body) {
    FirebaseFirestore firestore = FirebaseFirestore.getInstance();
    Map<String, Object> notification = new HashMap<>();
    notification.put("userid", recieverId);
    notification.put("title", "Anonim Chat" + "&data" + senderid + "&data" + name + "&data" + profilePic);
    notification.put("body", name + ": " + body);
    firestore.collection("Notifications").document(senderid).set(notification).addOnCompleteListener(task -> {
        if (task.isSuccessful()) {
            Log.w("test-message", "onComplete: bildirim başarıyla eklendi");
            firestore.collection("Notifications").document(senderid).delete();
        }
    }).addOnFailureListener(e -> Log.e("test-message", "onFailure: " + e.getLocalizedMessage()));

    firestore.collection("NotificationsBackup").document(senderid).set(notification).addOnSuccessListener(unused -> Log.w("test-message", "sendNotification: " + "bildirim yedeği alındı"));
}

我这样改变了方法,问题就解决了。我猜发生这个问题是因为addSnapShotListener不断检查数据库中的更改。我在onCreate()中获得了用户信息,问题得到了解决。

相关问题