diff --git a/.github/workflows/hermetic_library_generation.yaml b/.github/workflows/hermetic_library_generation.yaml
index 7838b82ee3..f611b78e29 100644
--- a/.github/workflows/hermetic_library_generation.yaml
+++ b/.github/workflows/hermetic_library_generation.yaml
@@ -37,7 +37,7 @@ jobs:
with:
fetch-depth: 0
token: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }}
- - uses: googleapis/sdk-platform-java/.github/scripts@v2.60.0
+ - uses: googleapis/sdk-platform-java/.github/scripts@v2.60.1
if: env.SHOULD_RUN == 'true'
with:
base_ref: ${{ github.base_ref }}
diff --git a/.github/workflows/unmanaged-dependency-check.yaml b/.github/workflows/unmanaged-dependency-check.yaml
index f2ddd24228..689f4bb4a0 100644
--- a/.github/workflows/unmanaged-dependency-check.yaml
+++ b/.github/workflows/unmanaged-dependency-check.yaml
@@ -14,6 +14,6 @@ jobs:
shell: bash
run: .kokoro/build.sh
- name: Unmanaged dependency check
- uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.50.0
+ uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.50.1
with:
bom-path: google-cloud-firestore-bom/pom.xml
diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg
index 475d1271a9..ee61380cf8 100644
--- a/.kokoro/presubmit/graalvm-native-a.cfg
+++ b/.kokoro/presubmit/graalvm-native-a.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.50.0" # {x-version-update:google-cloud-shared-dependencies:current}
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.50.1" # {x-version-update:google-cloud-shared-dependencies:current}
}
env_vars: {
diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg
index 0ec61ea39d..526f79dfa1 100644
--- a/.kokoro/presubmit/graalvm-native-b.cfg
+++ b/.kokoro/presubmit/graalvm-native-b.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.50.0" # {x-version-update:google-cloud-shared-dependencies:current}
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.50.1" # {x-version-update:google-cloud-shared-dependencies:current}
}
env_vars: {
diff --git a/.kokoro/presubmit/graalvm-native-c.cfg b/.kokoro/presubmit/graalvm-native-c.cfg
index 963711caeb..bbfc279a87 100644
--- a/.kokoro/presubmit/graalvm-native-c.cfg
+++ b/.kokoro/presubmit/graalvm-native-c.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.50.0" # {x-version-update:google-cloud-shared-dependencies:current}
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.50.1" # {x-version-update:google-cloud-shared-dependencies:current}
}
env_vars: {
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e2d40ff7ef..f04c145d69 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,26 @@
# Changelog
+## [3.31.9](https://github.com/googleapis/java-firestore/compare/v3.31.8...v3.31.9) (2025-07-11)
+
+
+### Bug Fixes
+
+* Improve performance of the UTF-8 string comparison logic. ([#2182](https://github.com/googleapis/java-firestore/issues/2182)) ([869a381](https://github.com/googleapis/java-firestore/commit/869a3814511f9a6e15641b3279bb871867886940))
+
+
+### Dependencies
+
+* Update dependency com.diffplug.spotless:spotless-maven-plugin to v2.45.0 ([#2184](https://github.com/googleapis/java-firestore/issues/2184)) ([88097cb](https://github.com/googleapis/java-firestore/commit/88097cbe8878b45897c89e102fa82e1975d2d74b))
+* Update dependency com.google.cloud:sdk-platform-java-config to v3.50.1 ([#2186](https://github.com/googleapis/java-firestore/issues/2186)) ([466e597](https://github.com/googleapis/java-firestore/commit/466e597c282533c0e500b57d27f386ef9ea99e5e))
+* Update dependency org.apache.commons:commons-lang3 to v3.18.0 ([#2187](https://github.com/googleapis/java-firestore/issues/2187)) ([1f3c20b](https://github.com/googleapis/java-firestore/commit/1f3c20b1923c3ae000359be91e7e39458c36ce2e))
+* Update googleapis/sdk-platform-java action to v2.60.0 ([#2176](https://github.com/googleapis/java-firestore/issues/2176)) ([8283a08](https://github.com/googleapis/java-firestore/commit/8283a08b1749e06864b50ab1813c13e9eb61c087))
+* Update googleapis/sdk-platform-java action to v2.60.1 ([#2181](https://github.com/googleapis/java-firestore/issues/2181)) ([be9daba](https://github.com/googleapis/java-firestore/commit/be9dabab8467a5aa3986d34f393d597d670af029))
+
+
+### Documentation
+
+* Add an example to the detailed comment in compareUtf8Strings() ([#2183](https://github.com/googleapis/java-firestore/issues/2183)) ([e16b158](https://github.com/googleapis/java-firestore/commit/e16b15853d6545c3c1476086c3bc88cb46991718))
+
## [3.31.8](https://github.com/googleapis/java-firestore/compare/v3.31.7...v3.31.8) (2025-07-02)
diff --git a/README.md b/README.md
index 9ebefdf62c..9e98fb6131 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-firestore
- 3.31.7
+ 3.31.8
```
@@ -56,13 +56,13 @@ implementation 'com.google.cloud:google-cloud-firestore'
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-firestore:3.31.8'
+implementation 'com.google.cloud:google-cloud-firestore:3.31.9'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-firestore" % "3.31.8"
+libraryDependencies += "com.google.cloud" % "google-cloud-firestore" % "3.31.9"
```
## Authentication
@@ -219,7 +219,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-firestore/java11.html
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-firestore.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-firestore/3.31.8
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-firestore/3.31.9
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/generation_config.yaml b/generation_config.yaml
index 572090409e..0ce8be713d 100644
--- a/generation_config.yaml
+++ b/generation_config.yaml
@@ -1,5 +1,5 @@
gapic_generator_version: 2.59.0
-googleapis_commitish: 63161c080e7eb3dd1d4fe76db1fad108b6ac9a27
+googleapis_commitish: e0ccc57ed01b0057222f865de5765b7e453cfd81
libraries_bom_version: 26.61.0
libraries:
- api_shortname: firestore
diff --git a/google-cloud-firestore-admin/pom.xml b/google-cloud-firestore-admin/pom.xml
index 0432ba1215..b843fd0ee5 100644
--- a/google-cloud-firestore-admin/pom.xml
+++ b/google-cloud-firestore-admin/pom.xml
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
google-cloud-firestore-admin
- 3.31.8
+ 3.31.9
jar
Google Cloud Firestore Admin Client
https://github.com/googleapis/java-firestore
@@ -14,7 +14,7 @@
com.google.cloud
google-cloud-firestore-parent
- 3.31.8
+ 3.31.9
diff --git a/google-cloud-firestore-bom/pom.xml b/google-cloud-firestore-bom/pom.xml
index 42647ce2b7..6990e2839b 100644
--- a/google-cloud-firestore-bom/pom.xml
+++ b/google-cloud-firestore-bom/pom.xml
@@ -3,12 +3,12 @@
4.0.0
com.google.cloud
google-cloud-firestore-bom
- 3.31.8
+ 3.31.9
pom
com.google.cloud
sdk-platform-java-config
- 3.50.0
+ 3.50.1
Google Cloud Firestore BOM
@@ -52,37 +52,37 @@
com.google.cloud
google-cloud-firestore
- 3.31.8
+ 3.31.9
com.google.cloud
google-cloud-firestore-admin
- 3.31.8
+ 3.31.9
com.google.api.grpc
grpc-google-cloud-firestore-admin-v1
- 3.31.8
+ 3.31.9
com.google.api.grpc
grpc-google-cloud-firestore-v1
- 3.31.8
+ 3.31.9
com.google.api.grpc
proto-google-cloud-firestore-admin-v1
- 3.31.8
+ 3.31.9
com.google.api.grpc
proto-google-cloud-firestore-v1
- 3.31.8
+ 3.31.9
com.google.cloud
proto-google-cloud-firestore-bundle-v1
- 3.31.8
+ 3.31.9
diff --git a/google-cloud-firestore/pom.xml b/google-cloud-firestore/pom.xml
index 1606ee730e..a57b746de9 100644
--- a/google-cloud-firestore/pom.xml
+++ b/google-cloud-firestore/pom.xml
@@ -2,7 +2,7 @@
4.0.0
google-cloud-firestore
- 3.31.8
+ 3.31.9
jar
Google Cloud Firestore
https://github.com/googleapis/java-firestore
@@ -12,7 +12,7 @@
com.google.cloud
google-cloud-firestore-parent
- 3.31.8
+ 3.31.9
google-cloud-firestore
@@ -199,7 +199,7 @@
org.apache.commons
commons-lang3
- 3.17.0
+ 3.18.0
test
@@ -291,7 +291,7 @@
com.diffplug.spotless
spotless-maven-plugin
- 2.44.5
+ 2.45.0
diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Order.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Order.java
index 7f37d8e05f..c382140227 100644
--- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Order.java
+++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Order.java
@@ -16,6 +16,8 @@
package com.google.cloud.firestore;
+import static java.lang.Character.isSurrogate;
+
import com.google.firestore.v1.MapValue;
import com.google.firestore.v1.Value;
import com.google.firestore.v1.Value.ValueTypeCase;
@@ -136,46 +138,62 @@ public int compare(@Nonnull Value left, @Nonnull Value right) {
/** Compare strings in UTF-8 encoded byte order */
public static int compareUtf8Strings(String left, String right) {
- int i = 0;
- while (i < left.length() && i < right.length()) {
- int leftCodePoint = left.codePointAt(i);
- int rightCodePoint = right.codePointAt(i);
-
- if (leftCodePoint != rightCodePoint) {
- if (leftCodePoint < 128 && rightCodePoint < 128) {
- // ASCII comparison
- return Integer.compare(leftCodePoint, rightCodePoint);
- } else {
- // UTF-8 encode the character at index i for byte comparison.
- ByteString leftBytes = ByteString.copyFromUtf8(getUtf8SafeBytes(left, i));
- ByteString rightBytes = ByteString.copyFromUtf8(getUtf8SafeBytes(right, i));
- int comp = compareByteStrings(leftBytes, rightBytes);
- if (comp != 0) {
- return comp;
- } else {
- // EXTREMELY RARE CASE: Code points differ, but their UTF-8 byte representations are
- // identical. This can happen with malformed input (invalid surrogate pairs), where
- // Java's encoding leads to unexpected byte sequences. Meanwhile, any invalid surrogate
- // inputs get converted to "?" by protocol buffer while round tripping, so we almost
- // never receive invalid strings from backend.
- // Fallback to code point comparison for graceful handling.
- return Integer.compare(leftCodePoint, rightCodePoint);
- }
- }
+ // noinspection StringEquality
+ if (left == right) {
+ return 0;
+ }
+
+ // Find the first differing character (a.k.a. "UTF-16 code unit") in the two strings and,
+ // if found, use that character to determine the relative ordering of the two strings as a
+ // whole. Comparing UTF-16 strings in UTF-8 byte order can be done simply and efficiently by
+ // comparing the UTF-16 code units (chars). This serendipitously works because of the way UTF-8
+ // and UTF-16 happen to represent Unicode code points.
+ //
+ // After finding the first pair of differing characters, there are two cases:
+ //
+ // Case 1: Both characters are non-surrogates (code points less than or equal to 0xFFFF) or
+ // both are surrogates from a surrogate pair (that collectively represent code points greater
+ // than 0xFFFF). In this case their numeric order as UTF-16 code units is the same as the
+ // lexicographical order of their corresponding UTF-8 byte sequences. A direct comparison is
+ // sufficient.
+ //
+ // Case 2: One character is a surrogate and the other is not. In this case the surrogate-
+ // containing string is always ordered after the non-surrogate. This is because surrogates are
+ // used to represent code points greater than 0xFFFF which have 4-byte UTF-8 representations
+ // and are lexicographically greater than the 1, 2, or 3-byte representations of code points
+ // less than or equal to 0xFFFF.
+ //
+ // An example of why Case 2 is required is comparing the following two Unicode code points:
+ //
+ // |-----------------------|------------|---------------------|-----------------|
+ // | Name | Code Point | UTF-8 Encoding | UTF-16 Encoding |
+ // |-----------------------|------------|---------------------|-----------------|
+ // | Replacement Character | U+FFFD | 0xEF 0xBF 0xBD | 0xFFFD |
+ // | Grinning Face | U+1F600 | 0xF0 0x9F 0x98 0x80 | 0xD83D 0xDE00 |
+ // |-----------------------|------------|---------------------|-----------------|
+ //
+ // A lexicographical comparison of the UTF-8 encodings of these code points would order
+ // "Replacement Character" _before_ "Grinning Face" because 0xEF is less than 0xF0. However, a
+ // direct comparison of the UTF-16 code units, as would be done in case 1, would erroneously
+ // produce the _opposite_ ordering, because 0xFFFD is _greater than_ 0xD83D. As it turns out,
+ // this relative ordering holds for all comparisons of UTF-16 code points requiring a surrogate
+ // pair with those that do not.
+ final int length = Math.min(left.length(), right.length());
+ for (int i = 0; i < length; i++) {
+ final char leftChar = left.charAt(i);
+ final char rightChar = right.charAt(i);
+ if (leftChar != rightChar) {
+ return (isSurrogate(leftChar) == isSurrogate(rightChar))
+ ? Character.compare(leftChar, rightChar)
+ : isSurrogate(leftChar) ? 1 : -1;
}
- // Increment by 2 for surrogate pairs, 1 otherwise.
- i += Character.charCount(leftCodePoint);
}
- // Compare lengths if all characters are equal
+ // Use the lengths of the strings to determine the overall comparison result since either the
+ // strings were equal or one is a prefix of the other.
return Integer.compare(left.length(), right.length());
}
- private static String getUtf8SafeBytes(String str, int index) {
- int firstCodePoint = str.codePointAt(index);
- return str.substring(index, index + Character.charCount(firstCodePoint));
- }
-
private int compareBlobs(Value left, Value right) {
ByteString leftBytes = left.getBytesValue();
ByteString rightBytes = right.getBytesValue();
diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/OrderTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/OrderTest.java
index 076cbf2db3..65e19d745f 100644
--- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/OrderTest.java
+++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/OrderTest.java
@@ -218,7 +218,7 @@ public void compareUtf8StringsShouldReturnCorrectValue() {
ByteString b2 = ByteString.copyFromUtf8(s2);
int expected = compareByteStrings(b1, b2);
- if (actual == expected) {
+ if (Integer.signum(actual) == Integer.signum(expected)) {
passCount++;
} else {
errors.add(
@@ -227,9 +227,12 @@ public void compareUtf8StringsShouldReturnCorrectValue() {
+ "\", s2=\""
+ s2
+ "\") returned "
+ + signName(actual)
+ + " ("
+ actual
+ + ")"
+ ", but expected "
- + expected
+ + signName(expected)
+ " (i="
+ i
+ ", s1.length="
@@ -252,6 +255,16 @@ public void compareUtf8StringsShouldReturnCorrectValue() {
}
}
+ private static String signName(int value) {
+ if (value < 0) {
+ return "a negative value";
+ } else if (value > 0) {
+ return "a positive value";
+ } else {
+ return "0";
+ }
+ }
+
private static class StringPairGenerator {
private final StringGenerator stringGenerator;
diff --git a/grpc-google-cloud-firestore-admin-v1/pom.xml b/grpc-google-cloud-firestore-admin-v1/pom.xml
index 7c1033b8a2..2e7df92f12 100644
--- a/grpc-google-cloud-firestore-admin-v1/pom.xml
+++ b/grpc-google-cloud-firestore-admin-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-firestore-admin-v1
- 3.31.8
+ 3.31.9
grpc-google-cloud-firestore-admin-v1
GRPC library for grpc-google-cloud-firestore-admin-v1
com.google.cloud
google-cloud-firestore-parent
- 3.31.8
+ 3.31.9
diff --git a/grpc-google-cloud-firestore-v1/pom.xml b/grpc-google-cloud-firestore-v1/pom.xml
index d14fa962dd..e99a7593d2 100644
--- a/grpc-google-cloud-firestore-v1/pom.xml
+++ b/grpc-google-cloud-firestore-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-firestore-v1
- 3.31.8
+ 3.31.9
grpc-google-cloud-firestore-v1
GRPC library for grpc-google-cloud-firestore-v1
com.google.cloud
google-cloud-firestore-parent
- 3.31.8
+ 3.31.9
diff --git a/pom.xml b/pom.xml
index 304086c490..8487ece924 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-firestore-parent
pom
- 3.31.8
+ 3.31.9
Google Cloud Firestore Parent
https://github.com/googleapis/java-firestore
@@ -14,7 +14,7 @@
com.google.cloud
sdk-platform-java-config
- 3.50.0
+ 3.50.1
@@ -150,32 +150,32 @@
com.google.api.grpc
proto-google-cloud-firestore-admin-v1
- 3.31.8
+ 3.31.9
com.google.cloud
google-cloud-firestore
- 3.31.8
+ 3.31.9
com.google.cloud
proto-google-cloud-firestore-bundle-v1
- 3.31.8
+ 3.31.9
com.google.api.grpc
proto-google-cloud-firestore-v1
- 3.31.8
+ 3.31.9
com.google.api.grpc
grpc-google-cloud-firestore-admin-v1
- 3.31.8
+ 3.31.9
com.google.api.grpc
grpc-google-cloud-firestore-v1
- 3.31.8
+ 3.31.9
diff --git a/proto-google-cloud-firestore-admin-v1/pom.xml b/proto-google-cloud-firestore-admin-v1/pom.xml
index e18fd4fca1..09e3b24519 100644
--- a/proto-google-cloud-firestore-admin-v1/pom.xml
+++ b/proto-google-cloud-firestore-admin-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-firestore-admin-v1
- 3.31.8
+ 3.31.9
proto-google-cloud-firestore-admin-v1
PROTO library for proto-google-cloud-firestore-admin-v1
com.google.cloud
google-cloud-firestore-parent
- 3.31.8
+ 3.31.9
diff --git a/proto-google-cloud-firestore-bundle-v1/pom.xml b/proto-google-cloud-firestore-bundle-v1/pom.xml
index 61b07b1f9b..d51249f92a 100644
--- a/proto-google-cloud-firestore-bundle-v1/pom.xml
+++ b/proto-google-cloud-firestore-bundle-v1/pom.xml
@@ -5,14 +5,14 @@
4.0.0
proto-google-cloud-firestore-bundle-v1
- 3.31.8
+ 3.31.9
proto-google-cloud-firestore-bundle-v1
PROTO library for proto-google-cloud-firestore-bundle-v1
com.google.cloud
google-cloud-firestore-parent
- 3.31.8
+ 3.31.9
diff --git a/proto-google-cloud-firestore-v1/pom.xml b/proto-google-cloud-firestore-v1/pom.xml
index 3d5c4ab84b..2c0616b644 100644
--- a/proto-google-cloud-firestore-v1/pom.xml
+++ b/proto-google-cloud-firestore-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-firestore-v1
- 3.31.8
+ 3.31.9
proto-google-cloud-firestore-v1
PROTO library for proto-google-cloud-firestore-v1
com.google.cloud
google-cloud-firestore-parent
- 3.31.8
+ 3.31.9
diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index 60762e92d6..a090324fd0 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -30,7 +30,7 @@
com.google.cloud
google-cloud-firestore
- 3.31.7
+ 3.31.8
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index 44e384cc31..6eb5321bb0 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -29,7 +29,7 @@
com.google.cloud
google-cloud-firestore
- 3.31.7
+ 3.31.8
diff --git a/versions.txt b/versions.txt
index 592c3e2110..7004033c29 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,11 +1,11 @@
# Format:
# module:released-version:current-version
-google-cloud-firestore:3.31.8:3.31.8
-google-cloud-firestore-admin:3.31.8:3.31.8
-google-cloud-firestore-bom:3.31.8:3.31.8
-grpc-google-cloud-firestore-admin-v1:3.31.8:3.31.8
-grpc-google-cloud-firestore-v1:3.31.8:3.31.8
-proto-google-cloud-firestore-admin-v1:3.31.8:3.31.8
-proto-google-cloud-firestore-v1:3.31.8:3.31.8
-proto-google-cloud-firestore-bundle-v1:3.31.8:3.31.8
+google-cloud-firestore:3.31.9:3.31.9
+google-cloud-firestore-admin:3.31.9:3.31.9
+google-cloud-firestore-bom:3.31.9:3.31.9
+grpc-google-cloud-firestore-admin-v1:3.31.9:3.31.9
+grpc-google-cloud-firestore-v1:3.31.9:3.31.9
+proto-google-cloud-firestore-admin-v1:3.31.9:3.31.9
+proto-google-cloud-firestore-v1:3.31.9:3.31.9
+proto-google-cloud-firestore-bundle-v1:3.31.9:3.31.9