FCM 通过主题触发两次推送通知

问题描述 投票:0回答:1

我正在和我的一个学生构建一个动物收养应用程序,我们遇到了以下错误,该错误似乎是自行出现的,因为我们甚至没有再次触及 FCM 部分:

步骤1

当我们向 Firestore 数据库添加新的 Animal 时,我们还通过 POST 发送推送通知(我们没有自定义后端,这是为了学校,所以我们这样做)

    private fun sendNotificationToServer(animal: Animal, animalId: String) {
        val retrofit = Retrofit.Builder()
            .baseUrl("https://fcm.googleapis.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val service = retrofit.create(FCMService::class.java)

        val notification = FCMNotification(
            to = "/topics/animales",
            notification = null,
            data = FCMAnimalData(
                idAnimal = animalId,
                tipoAnimal = animal.tipoAnimal.animalString,
                base64Image = "",
                title = "Nuevo animal",
                body = "Se ha añadido un nuevo animal a la lista. Haz clic para conocerlo!",
                timestamp = Timestamp.now().seconds
            )

        )

        val call = service.sendNotification(notification)

        call.enqueue(object : Callback<ResponseBody> {
            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                if (response.isSuccessful) {
                    Log.d("NOTIFICATION POST SUCCESS", response.message())
                } else {
                    Log.d("NOTIFICATION POST FAILURE1", response.message())
                }
            }

            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                Log.d("NOTIFICATION POST FAILURE2", t.message.toString())
            }
        })

    }

这按预期工作,我们在里面收到通知

MyFirebaseMessagingService

第2步

当然,我们重写

onMessageReceived
来处理通知。

在这里,我们获取通知的数据并将其插入 Firestore 集合(限制为 5),以便我们可以在应用程序中显示“通知历史记录”视图:

        val fcmData = remoteMessage.data
        sendNotification(fcmData["title"] as String, fcmData["body"] as String)
        firestore.collection(ALERTS_TABLE_NAME)
            .add(FCMAnimalData(
                base64Image = fcmData["base64Image"] as String,
                idAnimal = fcmData["idAnimal"] as String,
                tipoAnimal = fcmData["tipoAnimal"] as String,
                title = fcmData["title"] as String,
                body = fcmData["body"] as String,
                timestamp = fcmData["timestamp"]?.toLong() as Long
            )).addOnSuccessListener {
                Log.d("NOTIFICATION", "ADDED")
                firestore.collection(ALERTS_TABLE_NAME).get().addOnSuccessListener { notificationList ->
                    if (notificationList.size() > 5) {
                        firestore.collection(ALERTS_TABLE_NAME).document(notificationList.first().id).delete()
                    }
                }
            }

错误描述

预期:当我们进入应用程序的“通知历史记录”视图时,最后一条通知会出现一次

实际:通知在列表中出现重复

我们已经检查过令牌处理工作正常,实际上,在调试时我们发现我们只输入

onMessageReceived
一次,并且只收到一个推送通知。

查看 Firestore 集合时,我们可以看到以下内容:

  • 创建了两个相同的文档,一个带有 tipoAnimal =“Perro/Gato”,另一个带有 tipoAnimal =“”
  • 文档具有完全相同的时间戳。

自从我们开始将动物的类型发送到服务器以来,我们可能会收到此错误,但这应该不是问题,因为我们只发送一个字符串(animalString 值):

@Parcelize
data class Animal(
    @DocumentId var id: String = "",
    val nombre: String = "",
    val edad: Int = 0,
    val imagenBase64: String = "",
    val raza: String = "",
    val descripcion: String = "",
    var favorito: Boolean = false,
    val tipoAnimal: TipoAnimal = TipoAnimal.PERRO,
    val procedencia: TipoUsuario = TipoUsuario.PARTICULAR,
    val idUsuario: String = "",
    val timestamp: Long = 0
): Parcelable

enum class TipoAnimal(val animalString: String) {
    PERRO("Perro"),
    GATO("Gato")
}

提前感谢任何可以帮助我理解为什么通知会重复的人。

android firebase kotlin google-cloud-firestore firebase-cloud-messaging
1个回答
0
投票

几天后,我弄清楚发生了什么,这很明显,但直到现在我才看到。

引用我的问题:

我们已经检查过令牌处理工作正常,实际上,在调试时我们发现我们只输入 onMessageReceived 一次,并且只收到一个推送通知。

问题来了,我们将通知添加到

onMessageReceived
里面的数据库中,这意味着每个收到FCM推送通知的活动手机都会将通知插入数据库中。在我们的例子中,我们有两部手机,因此通知在“通知历史记录”片段中显示了两次。

我也会引用这个:

创建了两个相同的文档,一个带有 tipoAnimal =“Perro/Gato”,另一个带有 tipoAnimal =“”

这是因为我的学生正在使用没有该参数的旧版本应用程序,但 Firestore 通过设置默认值“”来管理它

© www.soinside.com 2019 - 2024. All rights reserved.