From c033a18958a78260fd9289c3f339ce881c629d24 Mon Sep 17 00:00:00 2001
From: Mark Duckworth <1124037+MarkDuckworth@users.noreply.github.com>
Date: Wed, 22 May 2024 11:57:50 -0600
Subject: [PATCH 1/6] Re-enable useFetchStreams in the updated WebChannel
 release. Added a test for the fixed WebChannel issue with reading multi-byte
 characters that are split across multiple streaming chunks.

---
 .../platform/browser/webchannel_connection.ts |  3 +-
 .../test/integration/api/query.test.ts        | 45 +++++++++++++++++++
 packages/webchannel-wrapper/src/index.d.ts    |  1 +
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/packages/firestore/src/platform/browser/webchannel_connection.ts b/packages/firestore/src/platform/browser/webchannel_connection.ts
index 5082418cf69..05cd79ecf9e 100644
--- a/packages/firestore/src/platform/browser/webchannel_connection.ts
+++ b/packages/firestore/src/platform/browser/webchannel_connection.ts
@@ -22,7 +22,6 @@ import {
   WebChannel,
   WebChannelError,
   WebChannelOptions,
-  FetchXmlHttpFactory,
   XhrIo,
   getStatEventTarget,
   EventTarget,
@@ -209,7 +208,7 @@ export class WebChannelConnection extends RestConnection {
     }
 
     if (this.useFetchStreams) {
-      request.xmlHttpFactory = new FetchXmlHttpFactory({});
+      request.useFetchStreams = true;
     }
 
     this.modifyHeadersForRequest(
diff --git a/packages/firestore/test/integration/api/query.test.ts b/packages/firestore/test/integration/api/query.test.ts
index bb2f35a6365..cf45c7b9693 100644
--- a/packages/firestore/test/integration/api/query.test.ts
+++ b/packages/firestore/test/integration/api/query.test.ts
@@ -2207,6 +2207,51 @@ apiDescribe('Queries', (persistence: boolean) => {
       }
     }
   }).timeout('90s');
+
+  it('can query large documents with multi-byte character strings', () => {
+    function randomMultiByteCharString(length: number): string {
+      const charCodes: number[] = [];
+
+      for (let i = 0; i < length; i++) {
+        charCodes.push(randInt(1, 65535));
+      }
+
+      return String.fromCharCode(...charCodes);
+    }
+
+    function randInt(min: number, max: number): number {
+      const scale = max - min + 1;
+      return Math.floor(Math.random() * scale);
+    }
+
+    let bigString = randomMultiByteCharString(10000);
+
+    // Encode and decode `bigString` to/from UTF-8 to
+    // ensure that any transformations applied during
+    // UTF-8 encoding are applied equally to the expected
+    // and actual results.
+    const te1 = new TextEncoder();
+    const textDecoder = new TextDecoder();
+    bigString = textDecoder.decode(te1.encode(bigString));
+
+    const doc = {
+      field: bigString
+    };
+
+    expect(bigString).to.deep.equal(bigString);
+
+    return withTestCollection(
+      persistence,
+      { 1: doc },
+      async collectionReference => {
+        const querySnap = await getDocs(collectionReference);
+        expect(querySnap.size).to.equal(1);
+
+        const fieldValue = querySnap.docs[0].get('field');
+        expect(fieldValue).to.deep.equal(bigString);
+      }
+    );
+  });
 });
 
 function verifyDocumentChange<T>(
diff --git a/packages/webchannel-wrapper/src/index.d.ts b/packages/webchannel-wrapper/src/index.d.ts
index 007287a5d9e..776bb8e8634 100644
--- a/packages/webchannel-wrapper/src/index.d.ts
+++ b/packages/webchannel-wrapper/src/index.d.ts
@@ -108,6 +108,7 @@ export interface WebChannelOptions {
   internalChannelParams?: {
     forwardChannelRequestTimeoutMs?: number;
   };
+  useFetchStreams?: boolean;
   xmlHttpFactory?: unknown;
   requestRefreshThresholds?: { [key: string]: number };
 }

From 79ca19d978944cc833444a924b554444cc760a19 Mon Sep 17 00:00:00 2001
From: Mark Duckworth <1124037+MarkDuckworth@users.noreply.github.com>
Date: Wed, 22 May 2024 12:03:43 -0600
Subject: [PATCH 2/6] Code cleanup.

---
 packages/firestore/test/integration/api/query.test.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/firestore/test/integration/api/query.test.ts b/packages/firestore/test/integration/api/query.test.ts
index cf45c7b9693..0caf8d413b5 100644
--- a/packages/firestore/test/integration/api/query.test.ts
+++ b/packages/firestore/test/integration/api/query.test.ts
@@ -2230,9 +2230,9 @@ apiDescribe('Queries', (persistence: boolean) => {
     // ensure that any transformations applied during
     // UTF-8 encoding are applied equally to the expected
     // and actual results.
-    const te1 = new TextEncoder();
+    const textEncoder = new TextEncoder();
     const textDecoder = new TextDecoder();
-    bigString = textDecoder.decode(te1.encode(bigString));
+    bigString = textDecoder.decode(textEncoder.encode(bigString));
 
     const doc = {
       field: bigString

From 2a8e83a1c397adf35b6dd3ae1f0be3b0d980aed3 Mon Sep 17 00:00:00 2001
From: Mark Duckworth <1124037+MarkDuckworth@users.noreply.github.com>
Date: Wed, 22 May 2024 12:12:17 -0600
Subject: [PATCH 3/6] Cleanup.

---
 packages/firestore/src/platform/browser/webchannel_connection.ts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/packages/firestore/src/platform/browser/webchannel_connection.ts b/packages/firestore/src/platform/browser/webchannel_connection.ts
index e6a6787cec8..83e8faef88a 100644
--- a/packages/firestore/src/platform/browser/webchannel_connection.ts
+++ b/packages/firestore/src/platform/browser/webchannel_connection.ts
@@ -27,7 +27,6 @@ import {
   EventTarget,
   StatEvent,
   Event,
-  FetchXmlHttpFactory,
   Stat
 } from '@firebase/webchannel-wrapper/webchannel-blob';
 

From 433d3072c0c9868475e6eea9bff01f2736f10993 Mon Sep 17 00:00:00 2001
From: Mark Duckworth <1124037+MarkDuckworth@users.noreply.github.com>
Date: Wed, 22 May 2024 12:20:10 -0600
Subject: [PATCH 4/6] Delete empty file.

---
 packages/webchannel-wrapper/src/index.d.ts | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 packages/webchannel-wrapper/src/index.d.ts

diff --git a/packages/webchannel-wrapper/src/index.d.ts b/packages/webchannel-wrapper/src/index.d.ts
deleted file mode 100644
index e69de29bb2d..00000000000

From 6a899b8dd4fc80c785638c4992043fce09e36668 Mon Sep 17 00:00:00 2001
From: Mark Duckworth <1124037+MarkDuckworth@users.noreply.github.com>
Date: Wed, 22 May 2024 12:22:23 -0600
Subject: [PATCH 5/6] Create sharp-dingos-admire.md

---
 .changeset/sharp-dingos-admire.md | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 .changeset/sharp-dingos-admire.md

diff --git a/.changeset/sharp-dingos-admire.md b/.changeset/sharp-dingos-admire.md
new file mode 100644
index 00000000000..3165adf640e
--- /dev/null
+++ b/.changeset/sharp-dingos-admire.md
@@ -0,0 +1,5 @@
+---
+"@firebase/firestore": patch
+---
+
+Re-enable useFetchStreams which was fixed in the last WebChannel release.

From 997499e8073f392678c3ba531955303f4c7354d4 Mon Sep 17 00:00:00 2001
From: Mark Duckworth <1124037+MarkDuckworth@users.noreply.github.com>
Date: Mon, 16 Sep 2024 08:49:27 -0600
Subject: [PATCH 6/6] Update sharp-dingos-admire.md

---
 .changeset/sharp-dingos-admire.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.changeset/sharp-dingos-admire.md b/.changeset/sharp-dingos-admire.md
index 3165adf640e..aeb1b082ad5 100644
--- a/.changeset/sharp-dingos-admire.md
+++ b/.changeset/sharp-dingos-admire.md
@@ -2,4 +2,4 @@
 "@firebase/firestore": patch
 ---
 
-Re-enable useFetchStreams which was fixed in the last WebChannel release.
+Re-enable useFetchStreams with the latest WebChannel implementation. This reduces the memory usage of WebChannel.