Skip to content

Commit cf716e0

Browse files
authored
dataconnect(change): add "X-Client-Platform" and "X-Client-Version" headers (#8486)
1 parent 1b63d4a commit cf716e0

5 files changed

Lines changed: 254 additions & 34 deletions

File tree

firebase-dataconnect/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
[#8446](https://github.com/firebase/firebase-android-sdk/pull/8446),
88
[#8456](https://github.com/firebase/firebase-android-sdk/pull/8456),
99
[#8460](https://github.com/firebase/firebase-android-sdk/pull/8460))
10+
- [changed] Add grpc request headers for platform name and sdk version
11+
to enable metrics collection in cloud monitoring.
12+
([#8486](https://github.com/firebase/firebase-android-sdk/pull/8486))
1013

1114
# 17.3.2
1215

firebase-dataconnect/src/androidTest/kotlin/com/google/firebase/dataconnect/GrpcMetadataIntegrationTest.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,23 @@ class GrpcMetadataIntegrationTest : DataConnectIntegrationTestBase() {
323323
val expectedAppId = getFirebaseAppIdFromStrings()
324324

325325
metadata.asClue {
326-
metadata.keys().shouldContainAll(googRequestParamsHeader.name(), googApiClientHeader.name())
326+
metadata
327+
.keys()
328+
.shouldContainAll(
329+
googRequestParamsHeader.name(),
330+
googApiClientHeader.name(),
331+
clientPlatformHeader.name(),
332+
clientVersionHeader.name(),
333+
)
327334
assertSoftly {
328335
// Do not verify "x-firebase-auth-token" here since that header is effectively tested by
329336
// AuthIntegrationTest
330337
metadata.get(googRequestParamsHeader) shouldBe
331338
"location=${dataConnect.config.location}&frontend=data"
332339
metadata.get(googApiClientHeader) shouldBe expectedGoogApiClientHeader(isFromGeneratedSdk)
333340
metadata.get(gmpAppIdHeader) shouldBe expectedAppId
341+
metadata.get(clientPlatformHeader) shouldBe "android"
342+
metadata.get(clientVersionHeader) shouldBe BuildConfig.VERSION_NAME
334343
}
335344
}
336345
}
@@ -469,6 +478,12 @@ class GrpcMetadataIntegrationTest : DataConnectIntegrationTestBase() {
469478
val googApiClientHeader: Metadata.Key<String> =
470479
Metadata.Key.of("x-goog-api-client", Metadata.ASCII_STRING_MARSHALLER)
471480

481+
val clientPlatformHeader: Metadata.Key<String> =
482+
Metadata.Key.of("x-client-platform", Metadata.ASCII_STRING_MARSHALLER)
483+
484+
val clientVersionHeader: Metadata.Key<String> =
485+
Metadata.Key.of("x-client-version", Metadata.ASCII_STRING_MARSHALLER)
486+
472487
private val gmpAppIdHeader: Metadata.Key<String> =
473488
Metadata.Key.of("x-firebase-gmpid", Metadata.ASCII_STRING_MARSHALLER)
474489

firebase-dataconnect/src/main/kotlin/com/google/firebase/dataconnect/core/DataConnectGrpcMetadata.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ internal class DataConnectGrpcMetadata(
8383
Metadata().also {
8484
it.put(googRequestParamsHeader, googRequestParamsHeaderValue)
8585
it.put(googApiClientHeader, googApiClientHeaderValue(callerSdkType))
86+
it.put(clientPlatformHeader, "android")
87+
it.put(clientVersionHeader, dataConnectSdkVersion)
8688
if (appId.isNotBlank()) {
8789
it.put(gmpAppIdHeader, appId)
8890
}
@@ -182,6 +184,12 @@ internal class DataConnectGrpcMetadata(
182184
private val googApiClientHeader: Metadata.Key<String> =
183185
Metadata.Key.of(GOOG_API_CLIENT_HEADER, Metadata.ASCII_STRING_MARSHALLER)
184186

187+
private val clientPlatformHeader: Metadata.Key<String> =
188+
Metadata.Key.of("x-client-platform", Metadata.ASCII_STRING_MARSHALLER)
189+
190+
private val clientVersionHeader: Metadata.Key<String> =
191+
Metadata.Key.of("x-client-version", Metadata.ASCII_STRING_MARSHALLER)
192+
185193
@Suppress("SpellCheckingInspection")
186194
private val gmpAppIdHeader: Metadata.Key<String> =
187195
Metadata.Key.of("x-firebase-gmpid", Metadata.ASCII_STRING_MARSHALLER)

firebase-dataconnect/src/test/kotlin/com/google/firebase/dataconnect/core/DataConnectGrpcMetadataUnitTest.kt

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -124,39 +124,49 @@ class DataConnectGrpcMetadataUnitTest {
124124
}
125125

126126
@Test
127-
fun `should include x-goog-request-params`() = runTest {
128-
val dataConnectGrpcMetadataArb =
129-
Arb.dataConnect.dataConnectGrpcMetadata(
130-
connectorLocation = Arb.constant("q8mgtztcz2"),
131-
)
127+
fun `should include x-goog-request-params`() =
128+
testMetadataIncludesHeader(
129+
dataConnectGrpcMetadataArb =
130+
Arb.dataConnect.dataConnectGrpcMetadata(
131+
connectorLocation = Arb.constant("q8mgtztcz2"),
132+
),
133+
headerName = "x-goog-request-params",
134+
getExpectedHeaderValue = { "location=q8mgtztcz2&frontend=data" },
135+
)
132136

133-
checkAll(
134-
propTestConfig,
135-
dataConnectGrpcMetadataArb,
136-
Arb.dataConnect.authTokenResult().orNull(nullProbability = 0.33),
137-
Arb.dataConnect.appCheckTokenResult().orNull(nullProbability = 0.33),
138-
Arb.enum<CallerSdkType>()
139-
) { dataConnectGrpcMetadata, authToken, appCheckToken, callerSdkType ->
140-
val metadata =
141-
dataConnectGrpcMetadata.get(
142-
authToken = authToken,
143-
appCheckToken = appCheckToken,
144-
callerSdkType = callerSdkType,
145-
)
137+
@Test
138+
fun `should include x-client-platform`() =
139+
testMetadataIncludesHeader(
140+
headerName = "x-client-platform",
141+
getExpectedHeaderValue = { "android" },
142+
)
146143

147-
metadata.asClue {
148-
it.keys() shouldContain "x-goog-request-params"
149-
val metadataKey = Metadata.Key.of("x-goog-request-params", Metadata.ASCII_STRING_MARSHALLER)
150-
it.get(metadataKey) shouldBe "location=q8mgtztcz2&frontend=data"
151-
}
152-
}
153-
}
144+
@Test
145+
fun `should include x-client-version`() =
146+
testMetadataIncludesHeader(
147+
dataConnectGrpcMetadataArb =
148+
Arb.dataConnect.dataConnectGrpcMetadata(
149+
dataConnectSdkVersion = Arb.constant("v3q46qc2ax"),
150+
),
151+
headerName = "x-client-version",
152+
getExpectedHeaderValue = { "v3q46qc2ax" },
153+
)
154154

155155
@Test
156-
fun `should include x-firebase-gmpid`() = runTest {
157-
val dataConnectGrpcMetadataArb =
158-
Arb.dataConnect.dataConnectGrpcMetadata(appId = Arb.constant("tvsxjeb745.appId"))
156+
fun `should include x-firebase-gmpid`() =
157+
testMetadataIncludesHeader(
158+
dataConnectGrpcMetadataArb =
159+
Arb.dataConnect.dataConnectGrpcMetadata(appId = Arb.constant("tvsxjeb745.appId")),
160+
headerName = "x-firebase-gmpid",
161+
getExpectedHeaderValue = { "tvsxjeb745.appId" },
162+
)
159163

164+
private fun testMetadataIncludesHeader(
165+
dataConnectGrpcMetadataArb: Arb<DataConnectGrpcMetadata> =
166+
Arb.dataConnect.dataConnectGrpcMetadata(),
167+
headerName: String,
168+
getExpectedHeaderValue: (DataConnectGrpcMetadata) -> String,
169+
) = runTest {
160170
checkAll(
161171
propTestConfig,
162172
dataConnectGrpcMetadataArb,
@@ -172,9 +182,9 @@ class DataConnectGrpcMetadataUnitTest {
172182
)
173183

174184
metadata.asClue {
175-
it.keys() shouldContain "x-firebase-gmpid"
176-
val metadataKey = Metadata.Key.of("x-firebase-gmpid", Metadata.ASCII_STRING_MARSHALLER)
177-
it.get(metadataKey) shouldBe "tvsxjeb745.appId"
185+
it.keys() shouldContain headerName.lowercase()
186+
val metadataKey = Metadata.Key.of(headerName, Metadata.ASCII_STRING_MARSHALLER)
187+
it.get(metadataKey) shouldBe getExpectedHeaderValue(dataConnectGrpcMetadata)
178188
}
179189
}
180190
}

0 commit comments

Comments
 (0)