From b0a3af243bd3e3cdd523b1d39276973ed6e22099 Mon Sep 17 00:00:00 2001 From: Tom Andersen Date: Wed, 3 Apr 2024 18:54:09 -0400 Subject: [PATCH 1/4] Allow Blob of data with zero length. --- .../Tests/Integration/API/FIRQueryTests.mm | 21 ++++++++++++ .../Integration/CodableIntegrationTests.swift | 34 +++++++++++++++++++ Firestore/core/src/nanopb/nanopb_util.h | 1 + 3 files changed, 56 insertions(+) diff --git a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm index 9afd1b469f1..3fa4b34617f 100644 --- a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm +++ b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm @@ -472,6 +472,27 @@ - (void)testCanHaveMultipleMutationsWhileOffline { ])); } +- (void)testCanHaveBlobMutationsWhileOffline { + FIRCollectionReference *col = [self collectionRef]; + + // set a few docs to known values + NSDictionary *initialDocs = @{@"doc1" : @{@"key1" : FSTTestData(0)}, @"doc2" : @{@"key2" : FSTTestData(1)}}; + [self writeAllDocuments:initialDocs toCollection:col]; + + // go offline for the rest of this test + [self disableNetwork]; + + // apply *multiple* mutations while offline + [[col documentWithPath:@"doc1"] setData:@{@"key1b" : FSTTestData(2)}]; + [[col documentWithPath:@"doc2"] setData:@{@"key2b" : FSTTestData(0)}]; + + FIRQuerySnapshot *result = [self readDocumentSetForRef:col]; + XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[ + @{@"key1b" : FSTTestData(2)}, + @{@"key2b" : FSTTestData(0)}, + ])); +} + - (void)testQueriesCanUseNotEqualFilters { // These documents are ordered by value in "zip" since notEquals filter is an inequality, which // results in documents being sorted by value. diff --git a/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift b/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift index 85a7e0ba014..19e921b087c 100644 --- a/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift +++ b/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift @@ -185,6 +185,40 @@ class CodableIntegrationTests: FSTIntegrationTestCase { } } + func testDataBlob() throws { + struct Model: Encodable { + var name: String + var data: Data + var emptyData: Data + } + let model = Model( + name: "name", + data: Data([1,2,3,4]), + emptyData: Data() + ) + + let docToWrite = documentRef() + + for flavor in allFlavors { + try setData(from: model, forDocument: docToWrite, withFlavor: flavor) + + let data = readDocument(forRef: docToWrite) + + XCTAssertEqual(data["data"] as! Data, Data([1,2,3,4]), "Failed with flavor \(flavor)") + XCTAssertEqual(data["emptyData"] as! Data, Data(), "Failed with flavor \(flavor)") + } + + db.disableNetwork() + defer { + db.enableNetwork() + } + + try docToWrite.setData(from: model) + let data = readDocument(forRef: docToWrite) + XCTAssertEqual(data["data"] as! Data, Data([1,2,3,4]), "Failed with flavor offline docRef") + XCTAssertEqual(data["emptyData"] as! Data, Data(), "Failed with flavor offline docRef") + } + func testExplicitNull() throws { struct Model: Encodable { var name: String diff --git a/Firestore/core/src/nanopb/nanopb_util.h b/Firestore/core/src/nanopb/nanopb_util.h index 6c551735e3e..f689cea1634 100644 --- a/Firestore/core/src/nanopb/nanopb_util.h +++ b/Firestore/core/src/nanopb/nanopb_util.h @@ -179,6 +179,7 @@ inline NSData* _Nonnull MakeNSData(const ByteString& str) { } inline NSData* _Nonnull MakeNSData(const pb_bytes_array_t* _Nullable data) { + if (data == nil) return [[NSData alloc] init]; return [[NSData alloc] initWithBytes:data->bytes length:data->size]; } From 7cb8351060e931502f70021e6084aa5acd30f22f Mon Sep 17 00:00:00 2001 From: Tom Andersen Date: Thu, 4 Apr 2024 10:12:58 -0400 Subject: [PATCH 2/4] Pretty --- Firestore/Example/Tests/Integration/API/FIRQueryTests.mm | 3 ++- .../Swift/Tests/Integration/CodableIntegrationTests.swift | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm index 3fa4b34617f..baf1641cc40 100644 --- a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm +++ b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm @@ -476,7 +476,8 @@ - (void)testCanHaveBlobMutationsWhileOffline { FIRCollectionReference *col = [self collectionRef]; // set a few docs to known values - NSDictionary *initialDocs = @{@"doc1" : @{@"key1" : FSTTestData(0)}, @"doc2" : @{@"key2" : FSTTestData(1)}}; + NSDictionary *initialDocs = + @{@"doc1" : @{@"key1" : FSTTestData(0)}, @"doc2" : @{@"key2" : FSTTestData(1)}}; [self writeAllDocuments:initialDocs toCollection:col]; // go offline for the rest of this test diff --git a/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift b/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift index 19e921b087c..e77435dd360 100644 --- a/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift +++ b/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift @@ -193,7 +193,7 @@ class CodableIntegrationTests: FSTIntegrationTestCase { } let model = Model( name: "name", - data: Data([1,2,3,4]), + data: Data([1, 2, 3, 4]), emptyData: Data() ) @@ -204,7 +204,7 @@ class CodableIntegrationTests: FSTIntegrationTestCase { let data = readDocument(forRef: docToWrite) - XCTAssertEqual(data["data"] as! Data, Data([1,2,3,4]), "Failed with flavor \(flavor)") + XCTAssertEqual(data["data"] as! Data, Data([1, 2, 3, 4]), "Failed with flavor \(flavor)") XCTAssertEqual(data["emptyData"] as! Data, Data(), "Failed with flavor \(flavor)") } @@ -215,7 +215,7 @@ class CodableIntegrationTests: FSTIntegrationTestCase { try docToWrite.setData(from: model) let data = readDocument(forRef: docToWrite) - XCTAssertEqual(data["data"] as! Data, Data([1,2,3,4]), "Failed with flavor offline docRef") + XCTAssertEqual(data["data"] as! Data, Data([1, 2, 3, 4]), "Failed with flavor offline docRef") XCTAssertEqual(data["emptyData"] as! Data, Data(), "Failed with flavor offline docRef") } From f771e92c815ff970a86996152ffd7a4509d7e582 Mon Sep 17 00:00:00 2001 From: Tom Andersen Date: Thu, 4 Apr 2024 11:00:16 -0400 Subject: [PATCH 3/4] Add changelog and fix --- Firestore/CHANGELOG.md | 3 +++ .../Tests/Integration/API/FIRQueryTests.mm | 22 ------------------- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/Firestore/CHANGELOG.md b/Firestore/CHANGELOG.md index d3e27b8442d..758d45b6c2e 100644 --- a/Firestore/CHANGELOG.md +++ b/Firestore/CHANGELOG.md @@ -1,3 +1,6 @@ +# Unreleased +- [fixed] Allow blob of data with zero length. (#11773, #12620) + # 10.24.0 - [feature] Enable queries with range & inequality filters on multiple fields. (#12416) diff --git a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm index baf1641cc40..9afd1b469f1 100644 --- a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm +++ b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm @@ -472,28 +472,6 @@ - (void)testCanHaveMultipleMutationsWhileOffline { ])); } -- (void)testCanHaveBlobMutationsWhileOffline { - FIRCollectionReference *col = [self collectionRef]; - - // set a few docs to known values - NSDictionary *initialDocs = - @{@"doc1" : @{@"key1" : FSTTestData(0)}, @"doc2" : @{@"key2" : FSTTestData(1)}}; - [self writeAllDocuments:initialDocs toCollection:col]; - - // go offline for the rest of this test - [self disableNetwork]; - - // apply *multiple* mutations while offline - [[col documentWithPath:@"doc1"] setData:@{@"key1b" : FSTTestData(2)}]; - [[col documentWithPath:@"doc2"] setData:@{@"key2b" : FSTTestData(0)}]; - - FIRQuerySnapshot *result = [self readDocumentSetForRef:col]; - XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[ - @{@"key1b" : FSTTestData(2)}, - @{@"key2b" : FSTTestData(0)}, - ])); -} - - (void)testQueriesCanUseNotEqualFilters { // These documents are ordered by value in "zip" since notEquals filter is an inequality, which // results in documents being sorted by value. From ac27a721d6f4064ee68ffcd81b2fb2a958bcace2 Mon Sep 17 00:00:00 2001 From: Tom Andersen Date: Thu, 4 Apr 2024 16:29:15 -0400 Subject: [PATCH 4/4] Fix --- .../Swift/Tests/Integration/CodableIntegrationTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift b/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift index e77435dd360..c6d01a63e98 100644 --- a/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift +++ b/Firestore/Swift/Tests/Integration/CodableIntegrationTests.swift @@ -208,9 +208,9 @@ class CodableIntegrationTests: FSTIntegrationTestCase { XCTAssertEqual(data["emptyData"] as! Data, Data(), "Failed with flavor \(flavor)") } - db.disableNetwork() + disableNetwork() defer { - db.enableNetwork() + enableNetwork() } try docToWrite.setData(from: model)