aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Michael Lehenbauer <mikelehen@gmail.com>2018-07-10 16:58:56 -0700
committerGravatar GitHub <noreply@github.com>2018-07-10 16:58:56 -0700
commit25f8691970a9f765a87ab3125776598c92e02744 (patch)
treeefdef14fd22c313411b9125d4804fd59aa114d5e
parent6466c35737eff21e9b48c3ce2353d42628f4bb77 (diff)
Expose array transforms and array contains queries. (#1514)
Also remove test code that was combining multiple array contains queries since those were disallowed in https://github.com/firebase/firebase-ios-sdk/commit/0ec836f9ca71b27fa54a11ae9e07e60b8c5cc002
-rw-r--r--Firestore/CHANGELOG.md4
-rw-r--r--Firestore/Example/SwiftBuildTest/main.swift10
-rw-r--r--Firestore/Example/Tests/Integration/API/FIRQueryTests.mm21
-rw-r--r--Firestore/Example/Tests/Integration/API/FIRValidationTests.mm1
-rw-r--r--Firestore/Source/API/FIRFieldValue+Internal.h28
-rw-r--r--Firestore/Source/API/FIRQuery+Internal.h37
-rw-r--r--Firestore/Source/Public/FIRFieldValue.h23
-rw-r--r--Firestore/Source/Public/FIRQuery.h32
8 files changed, 64 insertions, 92 deletions
diff --git a/Firestore/CHANGELOG.md b/Firestore/CHANGELOG.md
index c7b745d..8bb3e60 100644
--- a/Firestore/CHANGELOG.md
+++ b/Firestore/CHANGELOG.md
@@ -1,4 +1,8 @@
# Unreleased
+- [feature] Added `FieldValue.arrayUnion()` and `FieldValue.arrayRemove()` to
+ atomically add and remove elements from an array field in a document.
+- [feature] Added `whereField(arrayContains:)` query filter to find
+ documents where an array field contains a specific element.
# v0.12.5
- [changed] Internal improvements.
diff --git a/Firestore/Example/SwiftBuildTest/main.swift b/Firestore/Example/SwiftBuildTest/main.swift
index c5034da..6773511 100644
--- a/Firestore/Example/SwiftBuildTest/main.swift
+++ b/Firestore/Example/SwiftBuildTest/main.swift
@@ -83,9 +83,8 @@ func makeRefs(database db: Firestore) -> (CollectionReference, DocumentReference
func makeQuery(collection collectionRef: CollectionReference) -> Query {
let query = collectionRef.whereField(FieldPath(["name"]), isEqualTo: "Fred")
.whereField("age", isGreaterThanOrEqualTo: 24)
- // TODO(array-features): Uncomment when API is publicly exposed.
- // .whereField("tags", arrayContains:"active")
- // .whereField(FieldPath(["tags"]), arrayContains:"active")
+ .whereField("tags", arrayContains: "active")
+ .whereField(FieldPath(["tags"]), arrayContains: "active")
.whereField(FieldPath.documentID(), isEqualTo: "fred")
.order(by: FieldPath(["age"]))
.order(by: "name", descending: true)
@@ -106,9 +105,8 @@ func writeDocument(at docRef: DocumentReference) {
"bar.baz": 42,
FieldPath(["foobar"]): 42,
"server_timestamp": FieldValue.serverTimestamp(),
- // TODO(array-features): Uncomment once we add these to the public API
- // "array_union": FieldValue.arrayUnion(["a", "b"]),
- // "array_remove": FieldValue.arrayRemove(["a", "b"]),
+ "array_union": FieldValue.arrayUnion(["a", "b"]),
+ "array_remove": FieldValue.arrayRemove(["a", "b"]),
"field_delete": FieldValue.delete(),
] as [AnyHashable: Any]
diff --git a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm
index bdd3df1..e634d7f 100644
--- a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm
+++ b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm
@@ -20,7 +20,6 @@
#import "Firestore/Example/Tests/Util/FSTEventAccumulator.h"
#import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
-#import "Firestore/Source/API/FIRQuery+Internal.h"
@interface FIRQueryTests : FSTIntegrationTestCase
@end
@@ -293,8 +292,7 @@
]));
}
-// TODO(array-features): Enable once backend support lands.
-- (void)xtestArrayContainsQueries {
+- (void)testArrayContainsQueries {
NSDictionary *testDocs = @{
@"a" : @{@"array" : @[ @42 ]},
@"b" : @{@"array" : @[ @"a", @42, @"c" ]},
@@ -314,23 +312,6 @@
@"array2" : @[ @"bingo" ] }
]));
- // Search for "array" to contain both @42 and "a".
- snapshot = [self readDocumentSetForRef:[[collection queryWhereField:@"array" arrayContains:@42]
- queryWhereField:@"array"
- arrayContains:@"a"]];
- XCTAssertEqualObjects(FIRQuerySnapshotGetData(snapshot), (@[
- @{ @"array" : @[ @"a", @42, @"c" ] },
- ]));
-
- // Search two different array fields ("array" contains 42 and "array2" contains "bingo").
- snapshot = [self readDocumentSetForRef:[[collection queryWhereField:@"array" arrayContains:@42]
- queryWhereField:@"array2"
- arrayContains:@"bingo"]];
- XCTAssertEqualObjects(FIRQuerySnapshotGetData(snapshot), (@[
- @{ @"array" : @[ @42 ],
- @"array2" : @[ @"bingo" ] }
- ]));
-
// NOTE: The backend doesn't currently support null, NaN, objects, or arrays, so there isn't much
// of anything else interesting to test.
}
diff --git a/Firestore/Example/Tests/Integration/API/FIRValidationTests.mm b/Firestore/Example/Tests/Integration/API/FIRValidationTests.mm
index 599f1b2..fd37e5b 100644
--- a/Firestore/Example/Tests/Integration/API/FIRValidationTests.mm
+++ b/Firestore/Example/Tests/Integration/API/FIRValidationTests.mm
@@ -19,7 +19,6 @@
#import <XCTest/XCTest.h>
#import "Firestore/Source/API/FIRFieldValue+Internal.h"
-#import "Firestore/Source/API/FIRQuery+Internal.h"
#import "Firestore/Example/Tests/Util/FSTHelpers.h"
#import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
diff --git a/Firestore/Source/API/FIRFieldValue+Internal.h b/Firestore/Source/API/FIRFieldValue+Internal.h
index 883a307..1618cd4 100644
--- a/Firestore/Source/API/FIRFieldValue+Internal.h
+++ b/Firestore/Source/API/FIRFieldValue+Internal.h
@@ -54,32 +54,4 @@ NS_ASSUME_NONNULL_BEGIN
@property(strong, nonatomic, readonly) NSArray<id> *elements;
@end
-// TODO(array-features): Move to FIRFieldValue.h once backend support lands.
-@interface FIRFieldValue ()
-
-/**
- * Returns a special value that can be used with setData() or updateData() that tells the server to
- * union the given elements with any array value that already exists on the server. Each
- * specified element that doesn't already exist in the array will be added to the end. If the
- * field being modified is not already an array it will be overwritten with an array containing
- * exactly the specified elements.
- *
- * @param elements The elements to union into the array.
- * @return The FieldValue sentinel for use in a call to setData() or updateData().
- */
-+ (instancetype)fieldValueForArrayUnion:(NSArray<id> *)elements NS_SWIFT_NAME(arrayUnion(_:));
-
-/**
- * Returns a special value that can be used with setData() or updateData() that tells the server to
- * remove the given elements from any array value that already exists on the server. All
- * instances of each element specified will be removed from the array. If the field being
- * modified is not already an array it will be overwritten with an empty array.
- *
- * @param elements The elements to remove from the array.
- * @return The FieldValue sentinel for use in a call to setData() or updateData().
- */
-+ (instancetype)fieldValueForArrayRemove:(NSArray<id> *)elements NS_SWIFT_NAME(arrayRemove(_:));
-
-@end
-
NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/API/FIRQuery+Internal.h b/Firestore/Source/API/FIRQuery+Internal.h
index e207837..fa6c415 100644
--- a/Firestore/Source/API/FIRQuery+Internal.h
+++ b/Firestore/Source/API/FIRQuery+Internal.h
@@ -28,41 +28,4 @@ NS_ASSUME_NONNULL_BEGIN
@end
-// TODO(array-features): Move to FIRQuery.h once backend support is available.
-@interface FIRQuery ()
-
-/**
- * Creates and returns a new `FIRQuery` with the additional filter that documents must contain
- * the specified field, it must be an array, and the array must contain the provided value.
- *
- * A query can have only one arrayContains filter.
- *
- * @param field The name of the field containing an array to search
- * @param value The value that must be contained in the array
- *
- * @return The created `FIRQuery`.
- */
-// clang-format off
-- (FIRQuery *)queryWhereField:(NSString *)field
- arrayContains:(id)value NS_SWIFT_NAME(whereField(_:arrayContains:));
-// clang-format on
-
-/**
- * Creates and returns a new `FIRQuery` with the additional filter that documents must contain
- * the specified field, it must be an array, and the array must contain the provided value.
- *
- * A query can have only one arrayContains filter.
- *
- * @param path The path of the field containing an array to search
- * @param value The value that must be contained in the array
- *
- * @return The created `FIRQuery`.
- */
-// clang-format off
-- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path
- arrayContains:(id)value NS_SWIFT_NAME(whereField(_:arrayContains:));
-// clang-format on
-
-@end
-
NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Public/FIRFieldValue.h b/Firestore/Source/Public/FIRFieldValue.h
index 11a0da0..d896587 100644
--- a/Firestore/Source/Public/FIRFieldValue.h
+++ b/Firestore/Source/Public/FIRFieldValue.h
@@ -38,6 +38,29 @@ NS_SWIFT_NAME(FieldValue)
*/
+ (instancetype)fieldValueForServerTimestamp NS_SWIFT_NAME(serverTimestamp());
+/**
+ * Returns a special value that can be used with setData() or updateData() that tells the server to
+ * union the given elements with any array value that already exists on the server. Each
+ * specified element that doesn't already exist in the array will be added to the end. If the
+ * field being modified is not already an array it will be overwritten with an array containing
+ * exactly the specified elements.
+ *
+ * @param elements The elements to union into the array.
+ * @return The FieldValue sentinel for use in a call to setData() or updateData().
+ */
++ (instancetype)fieldValueForArrayUnion:(NSArray<id> *)elements NS_SWIFT_NAME(arrayUnion(_:));
+
+/**
+ * Returns a special value that can be used with setData() or updateData() that tells the server to
+ * remove the given elements from any array value that already exists on the server. All
+ * instances of each element specified will be removed from the array. If the field being
+ * modified is not already an array it will be overwritten with an empty array.
+ *
+ * @param elements The elements to remove from the array.
+ * @return The FieldValue sentinel for use in a call to setData() or updateData().
+ */
++ (instancetype)fieldValueForArrayRemove:(NSArray<id> *)elements NS_SWIFT_NAME(arrayRemove(_:));
+
@end
NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Public/FIRQuery.h b/Firestore/Source/Public/FIRQuery.h
index 799abcc..2b02a3c 100644
--- a/Firestore/Source/Public/FIRQuery.h
+++ b/Firestore/Source/Public/FIRQuery.h
@@ -239,6 +239,38 @@ addSnapshotListenerWithIncludeMetadataChanges:(BOOL)includeMetadataChanges
// clang-format on
/**
+ * Creates and returns a new `FIRQuery` with the additional filter that documents must contain
+ * the specified field, it must be an array, and the array must contain the provided value.
+ *
+ * A query can have only one arrayContains filter.
+ *
+ * @param field The name of the field containing an array to search
+ * @param value The value that must be contained in the array
+ *
+ * @return The created `FIRQuery`.
+ */
+// clang-format off
+- (FIRQuery *)queryWhereField:(NSString *)field
+ arrayContains:(id)value NS_SWIFT_NAME(whereField(_:arrayContains:));
+// clang-format on
+
+/**
+ * Creates and returns a new `FIRQuery` with the additional filter that documents must contain
+ * the specified field, it must be an array, and the array must contain the provided value.
+ *
+ * A query can have only one arrayContains filter.
+ *
+ * @param path The path of the field containing an array to search
+ * @param value The value that must be contained in the array
+ *
+ * @return The created `FIRQuery`.
+ */
+// clang-format off
+- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path
+ arrayContains:(id)value NS_SWIFT_NAME(whereField(_:arrayContains:));
+// clang-format on
+
+/**
* Creates and returns a new `FIRQuery` with the additional filter that documents must
* satisfy the specified predicate.
*