diff --git a/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt b/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt
index b25b97be95..6de8935315 100644
--- a/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt
+++ b/vector/src/main/java/im/vector/app/core/pushers/PushParser.kt
@@ -20,27 +20,26 @@ import im.vector.app.core.pushers.model.PushData
 import im.vector.app.core.pushers.model.PushDataFcm
 import im.vector.app.core.pushers.model.PushDataUnifiedPush
 import im.vector.app.core.pushers.model.toPushData
-import org.json.JSONObject
 import org.matrix.android.sdk.api.extensions.tryOrNull
 import org.matrix.android.sdk.api.util.MatrixJsonParser
 import javax.inject.Inject
 
+/**
+ * Parse the received data from Push. Json format are different depending on the source.
+ *
+ * Notifications received by FCM are formatted by the matrix gateway [1]. The data send to FCM is the content
+ * of the "notification" attribute of the json sent to the gateway [2][3].
+ * On the other side, with UnifiedPush, the content of the message received is the content posted to the push
+ * gateway endpoint [3].
+ *
+ * *Note*: If we want to get the same content with FCM and unifiedpush, we can do a new sygnal pusher [4].
+ *
+ * [1] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py
+ * [2] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py#L366
+ * [3] https://spec.matrix.org/latest/push-gateway-api/
+ * [4] https://github.com/p1gp1g/sygnal/blob/unifiedpush/sygnal/upfcmpushkin.py (Not tested for a while)
+ */
 class PushParser @Inject constructor() {
-    /**
-     * Parse the received data from Push. Json format are different depending on the source.
-     *
-     * Notifications received by FCM are formatted by the matrix gateway [1]. The data send to FCM is the content
-     * of the "notification" attribute of the json sent to the gateway [2][3].
-     * On the other side, with UnifiedPush, the content of the message received is the content posted to the push
-     * gateway endpoint [3].
-     *
-     * *Note*: If we want to get the same content with FCM and unifiedpush, we can do a new sygnal pusher [4].
-     *
-     * [1] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py
-     * [2] https://github.com/matrix-org/sygnal/blob/main/sygnal/gcmpushkin.py#L366
-     * [3] https://spec.matrix.org/latest/push-gateway-api/
-     * [4] https://github.com/p1gp1g/sygnal/blob/unifiedpush/sygnal/upfcmpushkin.py (Not tested for a while)
-     */
     fun parsePushDataUnifiedPush(message: ByteArray): PushData? {
         return MatrixJsonParser.getMoshi().let {
             tryOrNull { it.adapter(PushDataUnifiedPush::class.java).fromJson(String(message)) }?.toPushData()
@@ -48,8 +47,16 @@ class PushParser @Inject constructor() {
     }
 
     fun parsePushDataFcm(message: Map<*, *>): PushData? {
-        return MatrixJsonParser.getMoshi().let {
-            tryOrNull { it.adapter(PushDataFcm::class.java).fromJson(JSONObject(message).toString()) }?.toPushData()
+        if ((message.containsKey("event_id") && message["event_id"] !is String) ||
+                message.containsKey("room_id") && message["room_id"] !is String ||
+                message.containsKey("unread") && message["unread"] !is Int) {
+            return null
         }
+        val pushDataFcm = PushDataFcm(
+                eventId = message["event_id"] as String?,
+                roomId = message["room_id"] as String?,
+                unread = message["unread"] as Int?,
+        )
+        return pushDataFcm.toPushData()
     }
 }
diff --git a/vector/src/main/java/im/vector/app/core/pushers/model/PushDataFcm.kt b/vector/src/main/java/im/vector/app/core/pushers/model/PushDataFcm.kt
index 1b9c37ae0a..e78cdf5ff8 100644
--- a/vector/src/main/java/im/vector/app/core/pushers/model/PushDataFcm.kt
+++ b/vector/src/main/java/im/vector/app/core/pushers/model/PushDataFcm.kt
@@ -16,8 +16,6 @@
 
 package im.vector.app.core.pushers.model
 
-import com.squareup.moshi.Json
-import com.squareup.moshi.JsonClass
 import org.matrix.android.sdk.api.MatrixPatterns
 
 /**
@@ -32,11 +30,10 @@ import org.matrix.android.sdk.api.MatrixPatterns
  * </pre>
  * .
  */
-@JsonClass(generateAdapter = true)
 data class PushDataFcm(
-        @Json(name = "event_id") val eventId: String?,
-        @Json(name = "room_id") val roomId: String?,
-        @Json(name = "unread") var unread: Int?,
+        val eventId: String?,
+        val roomId: String?,
+        var unread: Int?,
 )
 
 fun PushDataFcm.toPushData() = PushData(
diff --git a/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt b/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt
index 03577a4400..9dcaa992f8 100644
--- a/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt
+++ b/vector/src/test/java/im/vector/app/core/pushers/PushParserTest.kt
@@ -35,73 +35,89 @@ class PushParserTest {
     )
 
     @Test
-    fun `test edge cases`() {
-        doAllEdgeTests(true)
-        doAllEdgeTests(false)
+    fun `test edge cases Firebase`() {
+        val pushParser = PushParser()
+        // Empty Json
+        pushParser.parsePushDataFcm(emptyMap<String, Any>()) shouldBeEqualTo emptyData
+        // Bad Json
+        pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("room_id", 5)) shouldBe null
+        pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("event_id", 5)) shouldBe null
+        pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("unread", "str")) shouldBe null
+        // Extra data
+        pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("extra", 5)) shouldBeEqualTo validData
     }
 
-    private fun doAllEdgeTests(firebaseFormat: Boolean) {
+    @Test
+    fun `test edge cases UnifiedPush`() {
         val pushParser = PushParser()
         // Empty string
-        pushParser.parseData("", firebaseFormat) shouldBe null
+        pushParser.parsePushDataUnifiedPush("".toByteArray()) shouldBe null
         // Empty Json
-        pushParser.parseData("{}", firebaseFormat) shouldBeEqualTo emptyData
+        pushParser.parsePushDataUnifiedPush("{}".toByteArray()) shouldBeEqualTo emptyData
         // Bad Json
-        pushParser.parseData("ABC", firebaseFormat) shouldBe null
+        pushParser.parsePushDataUnifiedPush("ABC".toByteArray()) shouldBe null
     }
 
     @Test
-    fun `test unified push format`() {
+    fun `test UnifiedPush format`() {
         val pushParser = PushParser()
-
-        pushParser.parseData(UNIFIED_PUSH_DATA, false) shouldBeEqualTo validData
-        pushParser.parseData(UNIFIED_PUSH_DATA, true) shouldBeEqualTo emptyData
+        pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.toByteArray()) shouldBeEqualTo validData
     }
 
     @Test
-    fun `test firebase push format`() {
+    fun `test Firebase format`() {
         val pushParser = PushParser()
-
-        pushParser.parseData(FIREBASE_PUSH_DATA, true) shouldBeEqualTo validData
-        pushParser.parseData(FIREBASE_PUSH_DATA, false) shouldBeEqualTo emptyData
+        pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA) shouldBeEqualTo validData
     }
 
     @Test
     fun `test empty roomId`() {
         val pushParser = PushParser()
-
-        pushParser.parseData(FIREBASE_PUSH_DATA.replace("!aRoomId:domain", ""), true) shouldBeEqualTo validData.copy(roomId = null)
-        pushParser.parseData(UNIFIED_PUSH_DATA.replace("!aRoomId:domain", ""), false) shouldBeEqualTo validData.copy(roomId = null)
+        val expected = validData.copy(roomId = null)
+        pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("room_id", "")) shouldBeEqualTo expected
+        pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.replace("!aRoomId:domain", "").toByteArray()) shouldBeEqualTo expected
     }
 
     @Test
     fun `test invalid roomId`() {
         val pushParser = PushParser()
-
-        pushParser.parseData(FIREBASE_PUSH_DATA.replace("!aRoomId:domain", "aRoomId:domain"), true) shouldBeEqualTo validData.copy(roomId = null)
-        pushParser.parseData(UNIFIED_PUSH_DATA.replace("!aRoomId:domain", "aRoomId:domain"), false) shouldBeEqualTo validData.copy(roomId = null)
+        val expected = validData.copy(roomId = null)
+        pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("room_id", "aRoomId:domain")) shouldBeEqualTo expected
+        pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.mutate("!aRoomId:domain", "aRoomId:domain")) shouldBeEqualTo expected
     }
 
     @Test
     fun `test empty eventId`() {
         val pushParser = PushParser()
-
-        pushParser.parseData(FIREBASE_PUSH_DATA.replace("\$anEventId", ""), true) shouldBeEqualTo validData.copy(eventId = null)
-        pushParser.parseData(UNIFIED_PUSH_DATA.replace("\$anEventId", ""), false) shouldBeEqualTo validData.copy(eventId = null)
+        val expected = validData.copy(eventId = null)
+        pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("event_id", "")) shouldBeEqualTo expected
+        pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.mutate("\$anEventId", "")) shouldBeEqualTo expected
     }
 
     @Test
     fun `test invalid eventId`() {
         val pushParser = PushParser()
-
-        pushParser.parseData(FIREBASE_PUSH_DATA.replace("\$anEventId", "anEventId"), true) shouldBeEqualTo validData.copy(eventId = null)
-        pushParser.parseData(UNIFIED_PUSH_DATA.replace("\$anEventId", "anEventId"), false) shouldBeEqualTo validData.copy(eventId = null)
+        val expected = validData.copy(eventId = null)
+        pushParser.parsePushDataFcm(FIREBASE_PUSH_DATA.mutate("event_id", "anEventId")) shouldBeEqualTo expected
+        pushParser.parsePushDataUnifiedPush(UNIFIED_PUSH_DATA.mutate("\$anEventId", "anEventId")) shouldBeEqualTo expected
     }
 
     companion object {
         private const val UNIFIED_PUSH_DATA =
                 "{\"notification\":{\"event_id\":\"\$anEventId\",\"room_id\":\"!aRoomId:domain\",\"counts\":{\"unread\":1},\"prio\":\"high\"}}"
-        private const val FIREBASE_PUSH_DATA =
-                "{\"event_id\":\"\$anEventId\",\"room_id\":\"!aRoomId:domain\",\"unread\":\"1\",\"prio\":\"high\"}"
+        private val FIREBASE_PUSH_DATA = mapOf(
+                "event_id" to "\$anEventId",
+                "room_id" to "!aRoomId:domain",
+                "unread" to 1,
+                "prio" to "high",
+        )
     }
 }
+
+private fun <K, V> Map<K, V?>.mutate(key: K, value: V?): Map<K, V?> {
+    return toMutableMap().apply { put(key, value) }
+}
+
+private fun String.mutate(oldValue: String, newValue: String): ByteArray {
+    return replace(oldValue, newValue).toByteArray()
+}