diff --git a/app/src/main/java/com/jttools/datacontrol/remote/FirebaseConfig.kt b/app/src/main/java/com/jttools/datacontrol/remote/FirebaseConfig.kt index 4798b7d..106983e 100644 --- a/app/src/main/java/com/jttools/datacontrol/remote/FirebaseConfig.kt +++ b/app/src/main/java/com/jttools/datacontrol/remote/FirebaseConfig.kt @@ -7,7 +7,7 @@ data class FirebaseConfig(val apiKey: String, val appId: String, val projectId: companion object { /** * Lit ce que l'utilisateur colle : le bloc `firebaseConfig` de la console (JavaScript), un JSON, - * ou une chaîne « fc1:… » partagée par FamilyControl. Renvoie null si apiKey, appId ou projectId manque. + * le fichier google-services.json, ou une chaîne « fc1:… » partagée par FamilyControl. Renvoie null si apiKey, appId ou projectId manque. */ fun parse(input: String): FirebaseConfig? { val text = input.trim() @@ -17,9 +17,17 @@ data class FirebaseConfig(val apiKey: String, val appId: String, val projectId: build(json.optString("apiKey"), json.optString("appId"), json.optString("projectId")) }.getOrNull() } - fun pick(name: String) = - Regex("""["']?$name["']?\s*[:=]\s*["']([^"']+)["']""").find(text)?.groupValues?.get(1) - return build(pick("apiKey"), pick("appId"), pick("projectId")) + // Guillemets typographiques (souvent insérés par un copier-coller sur téléphone) → droits. + val plain = text.replace(Regex("[“”„«»]"), "\"").replace(Regex("[‘’]"), "'") + // Noms du bloc Web (apiKey…) ou du fichier google-services.json de l'application Android. + fun pick(vararg names: String) = names.firstNotNullOfOrNull { name -> + Regex("""["']?\b$name["']?\s*[:=]\s*["']\s*([^"'\s]+)\s*["']""").find(plain)?.groupValues?.get(1) + } + return build( + pick("apiKey", "current_key"), + pick("appId", "mobilesdk_app_id"), + pick("projectId", "project_id") + ) } private fun build(apiKey: String?, appId: String?, projectId: String?): FirebaseConfig? = diff --git a/app/src/test/java/com/jttools/datacontrol/remote/FirebaseConfigTest.kt b/app/src/test/java/com/jttools/datacontrol/remote/FirebaseConfigTest.kt index e53f5e4..e0ee7d7 100644 --- a/app/src/test/java/com/jttools/datacontrol/remote/FirebaseConfigTest.kt +++ b/app/src/test/java/com/jttools/datacontrol/remote/FirebaseConfigTest.kt @@ -35,6 +35,25 @@ class FirebaseConfigTest { assertEquals(expected, FirebaseConfig.parse(" fc1:${b64.chunked(20).joinToString("\n")} ")) } + @Test fun `guillemets typographiques`() { + val js = "apiKey: “AIzaTest”, projectId: «mon-projet», appId: ‘1:123:android:abc’" + assertEquals(expected, FirebaseConfig.parse(js)) + } + + @Test fun `fichier google-services json`() { + val gs = """ + { + "project_info": { "project_number": "123", "project_id": "mon-projet", "storage_bucket": "mon-projet.appspot.com" }, + "client": [ { + "client_info": { "mobilesdk_app_id": "1:123:android:abc", + "android_client_info": { "package_name": "com.jttools.datacontrol" } }, + "api_key": [ { "current_key": "AIzaTest" } ] + } ] + } + """.trimIndent() + assertEquals(expected, FirebaseConfig.parse(gs)) + } + @Test fun `champ manquant ou illisible`() { assertNull(FirebaseConfig.parse("""{"apiKey":"AIzaTest","projectId":"mon-projet"}""")) assertNull(FirebaseConfig.parse("fc1:!!!"))