diff options
Diffstat (limited to 'Firestore')
-rw-r--r-- | Firestore/Example/Tests/Integration/API/FIRServerTimestampTests.m | 136 | ||||
-rw-r--r-- | Firestore/Example/Tests/Model/FSTMutationTests.m | 31 | ||||
-rw-r--r-- | Firestore/Source/API/FIRDocumentSnapshot.m | 18 | ||||
-rw-r--r-- | Firestore/Source/API/FIRSnapshotOptions+Internal.h | 6 | ||||
-rw-r--r-- | Firestore/Source/API/FIRSnapshotOptions.m | 28 | ||||
-rw-r--r-- | Firestore/Source/Model/FSTFieldValue.h | 15 | ||||
-rw-r--r-- | Firestore/Source/Model/FSTFieldValue.m | 32 | ||||
-rw-r--r-- | Firestore/Source/Model/FSTMutation.h | 12 | ||||
-rw-r--r-- | Firestore/Source/Model/FSTMutation.m | 53 | ||||
-rw-r--r-- | Firestore/Source/Model/FSTMutationBatch.m | 2 | ||||
-rw-r--r-- | Firestore/Source/Public/FIRDocumentSnapshot.h | 10 |
11 files changed, 164 insertions, 179 deletions
diff --git a/Firestore/Example/Tests/Integration/API/FIRServerTimestampTests.m b/Firestore/Example/Tests/Integration/API/FIRServerTimestampTests.m index 5b210d7..8d931ec 100644 --- a/Firestore/Example/Tests/Integration/API/FIRServerTimestampTests.m +++ b/Firestore/Example/Tests/Integration/API/FIRServerTimestampTests.m @@ -16,16 +16,14 @@ @import FirebaseFirestore; -#import <FirebaseFirestore/FIRDocumentReference.h> #import <FirebaseFirestore/FIRDocumentSnapshot.h> -#import <Firestore/Source/Core/FSTFirestoreClient.h> #import <OCMock/OCMArg.h> #import <XCTest/XCTest.h> -#import "Firestore/Source/API/FIRFirestore+Internal.h" - #import "Firestore/Example/Tests/Util/FSTEventAccumulator.h" #import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/Core/FSTFirestoreClient.h" @interface FIRServerTimestampTests : FSTIntegrationTestCase @end @@ -48,17 +46,17 @@ id<FIRListenerRegistration> _listenerRegistration; // Snapshot options that return the previous value for pending server timestamps. - FIRSnapshotOptions *_previousValue; - FIRSnapshotOptions *_estimateValue; + FIRSnapshotOptions *_returnPreviousValue; + FIRSnapshotOptions *_returnEstimatedValue; } - (void)setUp { [super setUp]; - _previousValue = - [FIRSnapshotOptions setServerTimestampBehavior:FIRServerTimestampBehaviorPrevious]; - _estimateValue = - [FIRSnapshotOptions setServerTimestampBehavior:FIRServerTimestampBehaviorEstimate]; + _returnPreviousValue = + [FIRSnapshotOptions serverTimestampBehavior:FIRServerTimestampBehaviorPrevious]; + _returnEstimatedValue = + [FIRSnapshotOptions serverTimestampBehavior:FIRServerTimestampBehaviorEstimate]; // Data written in tests via set. _setData = @{ @@ -92,7 +90,7 @@ #pragma mark - Test Helpers /** Returns the expected data, with the specified timestamp substituted in. */ -- (NSDictionary *)expectedDataWithTimestamp:(id _Nullable)timestamp { +- (NSDictionary *)expectedDataWithTimestamp:(nullable id)timestamp { return @{ @"a" : @42, @"when" : timestamp, @"deep" : @{@"when" : timestamp} }; } @@ -105,55 +103,53 @@ /** Waits for a snapshot with local writes. */ - (FIRDocumentSnapshot *)waitForLocalEvent { - return [_accumulator awaitEventWithName:@"Local event."]; + FIRDocumentSnapshot *snapshot = [_accumulator awaitEventWithName:@"Local event."]; + XCTAssertTrue(snapshot.metadata.hasPendingWrites); + return snapshot; +} + +/** Waits for a snapshot with that has no pending writes */ +- (FIRDocumentSnapshot *)waitForRemoteEvent { + FIRDocumentSnapshot *snapshot = [_accumulator awaitEventWithName:@"Remote event."]; + XCTAssertFalse(snapshot.metadata.hasPendingWrites); + return snapshot; } -/** Waits for a snapshot containing _setData but with NSNull for the timestamps. */ -- (FIRDocumentSnapshot *)waitForLocalEventWithNullTimestamps { - FIRDocumentSnapshot *localSnap = [self waitForLocalEvent]; - XCTAssertEqualObjects(localSnap.data, [self expectedDataWithTimestamp:[NSNull null]]); - return localSnap; +/** Verifies a snapshot containing _setData but with NSNull for the timestamps. */ +- (void)verifySnapshotWithNullTimestamps:(FIRDocumentSnapshot *)snapshot { + XCTAssertEqualObjects(snapshot.data, [self expectedDataWithTimestamp:[NSNull null]]); } -/** Waits for a snapshot containing _setData but with a local estimate for the timestamps. */ -- (FIRDocumentSnapshot *)waitForLocalEventWithEstimatedTimestamps { - FIRDocumentSnapshot *localSnap = [self waitForLocalEvent]; - id timestamp = [localSnap valueForField:@"when" options:_estimateValue]; +/** Verifies a snapshot containing _setData but with a local estimate for the timestamps. */ +- (void)verifySnapshotWithEstimatedTimestamps:(FIRDocumentSnapshot *)snapshot { + id timestamp = [snapshot valueForField:@"when" options:_returnEstimatedValue]; XCTAssertTrue([timestamp isKindOfClass:[NSDate class]]); - XCTAssertEqualObjects([localSnap dataWithOptions:_estimateValue], + XCTAssertEqualObjects([snapshot dataWithOptions:_returnEstimatedValue], [self expectedDataWithTimestamp:timestamp]); - return localSnap; } -/** Waits for a snapshot containing _setData but using the previous field value for the timestamps. */ -- (FIRDocumentSnapshot *)waitForLocalEventWithPreviousDataFromSnapshot: - (FIRDocumentSnapshot *_Nullable)previousSnapshot { - FIRDocumentSnapshot *localSnap = [self waitForLocalEvent]; - +/** Verifies a snapshot containing _setData but using the previous field value for the timestamps. */ +- (void)verifySnapshot:(FIRDocumentSnapshot *)snapshot + withDataFromPreviousSnapshot:(nullable FIRDocumentSnapshot *)previousSnapshot { if (previousSnapshot == nil) { - XCTAssertEqualObjects([localSnap dataWithOptions:_previousValue], + XCTAssertEqualObjects([snapshot dataWithOptions:_returnPreviousValue], [self expectedDataWithTimestamp:[NSNull null]]); } else { - XCTAssertEqualObjects([localSnap dataWithOptions:_previousValue], + XCTAssertEqualObjects([snapshot dataWithOptions:_returnPreviousValue], [self expectedDataWithTimestamp:previousSnapshot[@"when"]]); } - - return localSnap; } /** Waits for a snapshot containing _setData but with resolved server timestamps. */ -- (FIRDocumentSnapshot *)waitForRemoteEvent { - // server event should have a resolved timestamp; verify it. - FIRDocumentSnapshot *remoteSnap = [_accumulator awaitEventWithName:@"Remote event"]; - XCTAssertTrue(remoteSnap.exists); - NSDate *when = remoteSnap[@"when"]; +- (id)verifySnapshotWithResolvedTimestamps:(FIRDocumentSnapshot *)snapshot { + XCTAssertTrue(snapshot.exists); + NSDate *when = snapshot[@"when"]; XCTAssertTrue([when isKindOfClass:[NSDate class]]); // Tolerate up to 10 seconds of clock skew between client and server. XCTAssertEqualWithAccuracy(when.timeIntervalSinceNow, 0, 10); // Validate the rest of the document. - XCTAssertEqualObjects(remoteSnap.data, [self expectedDataWithTimestamp:when]); - return remoteSnap; + XCTAssertEqualObjects(snapshot.data, [self expectedDataWithTimestamp:when]); } /** Runs a transaction block. */ @@ -186,85 +182,85 @@ - (void)testServerTimestampsWorkViaSet { [self writeDocumentRef:_docRef data:_setData]; - [self waitForLocalEventWithNullTimestamps]; - [self waitForRemoteEvent]; + [self verifySnapshotWithNullTimestamps:[self waitForLocalEvent]]; + [self verifySnapshotWithResolvedTimestamps:[self waitForRemoteEvent]]; } - (void)testServerTimestampsWorkViaUpdate { [self writeInitialData]; [self updateDocumentRef:_docRef data:_updateData]; - [self waitForLocalEventWithNullTimestamps]; - [self waitForRemoteEvent]; + [self verifySnapshotWithNullTimestamps:[self waitForLocalEvent]]; + [self verifySnapshotWithResolvedTimestamps:[self waitForRemoteEvent]]; } - (void)testServerTimestampsWithEstimatedValue { [self writeDocumentRef:_docRef data:_setData]; - [self waitForLocalEventWithEstimatedTimestamps]; - [self waitForRemoteEvent]; + [self verifySnapshotWithEstimatedTimestamps:[self waitForLocalEvent]]; + [self verifySnapshotWithResolvedTimestamps:[self waitForRemoteEvent]]; } - (void)testServerTimestampsWithPreviousValue { [self writeDocumentRef:_docRef data:_setData]; - [self waitForLocalEventWithPreviousDataFromSnapshot:nil]; + [self verifySnapshot:[self waitForLocalEvent] withDataFromPreviousSnapshot:nil]; FIRDocumentSnapshot *remoteSnapshot = [self waitForRemoteEvent]; [_docRef updateData:_updateData]; - [self waitForLocalEventWithPreviousDataFromSnapshot:remoteSnapshot]; + [self verifySnapshot:[self waitForLocalEvent] withDataFromPreviousSnapshot:remoteSnapshot]; - [self waitForRemoteEvent]; + [self verifySnapshotWithResolvedTimestamps:[self waitForRemoteEvent]]; } - (void)testServerTimestampsWithPreviousValueOfDifferentType { [self writeDocumentRef:_docRef data:_setData]; - [self waitForLocalEvent]; - [self waitForRemoteEvent]; + [self verifySnapshot:[self waitForLocalEvent] withDataFromPreviousSnapshot:nil]; + [self verifySnapshotWithResolvedTimestamps:[self waitForRemoteEvent]]; [_docRef updateData:@{@"a" : [FIRFieldValue fieldValueForServerTimestamp]}]; FIRDocumentSnapshot *localSnapshot = [self waitForLocalEvent]; XCTAssertEqualObjects([localSnapshot valueForField:@"a"], [NSNull null]); - XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_previousValue], @42); - XCTAssertTrue( - [[localSnapshot valueForField:@"a" options:_estimateValue] isKindOfClass:[NSDate class]]); + XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_returnPreviousValue], @42); + XCTAssertTrue([[localSnapshot valueForField:@"a" options:_returnEstimatedValue] + isKindOfClass:[NSDate class]]); - FIRDocumentSnapshot *remoteSnapshot = [_accumulator awaitEventWithName:@"Remote event"]; + FIRDocumentSnapshot *remoteSnapshot = [self waitForRemoteEvent]; XCTAssertTrue([[remoteSnapshot valueForField:@"a"] isKindOfClass:[NSDate class]]); - XCTAssertTrue( - [[remoteSnapshot valueForField:@"a" options:_previousValue] isKindOfClass:[NSDate class]]); - XCTAssertTrue( - [[remoteSnapshot valueForField:@"a" options:_estimateValue] isKindOfClass:[NSDate class]]); + XCTAssertTrue([[remoteSnapshot valueForField:@"a" options:_returnPreviousValue] + isKindOfClass:[NSDate class]]); + XCTAssertTrue([[remoteSnapshot valueForField:@"a" options:_returnEstimatedValue] + isKindOfClass:[NSDate class]]); } - (void)testServerTimestampsWithConsecutiveUpdates { [self writeDocumentRef:_docRef data:_setData]; - [self waitForLocalEvent]; - [self waitForRemoteEvent]; + [self verifySnapshot:[self waitForLocalEvent] withDataFromPreviousSnapshot:nil]; + [self verifySnapshotWithResolvedTimestamps:[self waitForRemoteEvent]]; [self disableNetwork]; [_docRef updateData:@{@"a" : [FIRFieldValue fieldValueForServerTimestamp]}]; FIRDocumentSnapshot *localSnapshot = [self waitForLocalEvent]; - XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_previousValue], @42); + XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_returnPreviousValue], @42); [_docRef updateData:@{@"a" : [FIRFieldValue fieldValueForServerTimestamp]}]; localSnapshot = [self waitForLocalEvent]; - XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_previousValue], @42); + XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_returnPreviousValue], @42); [self enableNetwork]; - FIRDocumentSnapshot *remoteSnapshot = [_accumulator awaitEventWithName:@"Remote event"]; + FIRDocumentSnapshot *remoteSnapshot = [self waitForRemoteEvent]; XCTAssertTrue([[remoteSnapshot valueForField:@"a"] isKindOfClass:[NSDate class]]); } - (void)testServerTimestampsPreviousValueFromLocalMutation { [self writeDocumentRef:_docRef data:_setData]; - [self waitForLocalEvent]; - [self waitForRemoteEvent]; + [self verifySnapshot:[self waitForLocalEvent] withDataFromPreviousSnapshot:nil]; + [self verifySnapshotWithResolvedTimestamps:[self waitForRemoteEvent]]; [self disableNetwork]; [_docRef updateData:@{@"a" : [FIRFieldValue fieldValueForServerTimestamp]}]; FIRDocumentSnapshot *localSnapshot = [self waitForLocalEvent]; - XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_previousValue], @42); + XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_returnPreviousValue], @42); [_docRef updateData:@{ @"a" : @1337 }]; localSnapshot = [self waitForLocalEvent]; @@ -272,11 +268,11 @@ [_docRef updateData:@{@"a" : [FIRFieldValue fieldValueForServerTimestamp]}]; localSnapshot = [self waitForLocalEvent]; - XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_previousValue], @1337); + XCTAssertEqualObjects([localSnapshot valueForField:@"a" options:_returnPreviousValue], @1337); [self enableNetwork]; - FIRDocumentSnapshot *remoteSnapshot = [_accumulator awaitEventWithName:@"Remote event"]; + FIRDocumentSnapshot *remoteSnapshot = [self waitForRemoteEvent]; XCTAssertTrue([[remoteSnapshot valueForField:@"a"] isKindOfClass:[NSDate class]]); } @@ -285,7 +281,7 @@ [transaction setData:_setData forDocument:_docRef]; }]; - [self waitForRemoteEvent]; + [self verifySnapshotWithResolvedTimestamps:[self waitForRemoteEvent]]; } - (void)testServerTimestampsWorkViaTransactionUpdate { @@ -293,7 +289,7 @@ [self runTransactionBlock:^(FIRTransaction *transaction) { [transaction updateData:_updateData forDocument:_docRef]; }]; - [self waitForRemoteEvent]; + [self verifySnapshotWithResolvedTimestamps:[self waitForRemoteEvent]]; } - (void)testServerTimestampsFailViaUpdateOnNonexistentDocument { diff --git a/Firestore/Example/Tests/Model/FSTMutationTests.m b/Firestore/Example/Tests/Model/FSTMutationTests.m index 4c5a4ad..f5131f5 100644 --- a/Firestore/Example/Tests/Model/FSTMutationTests.m +++ b/Firestore/Example/Tests/Model/FSTMutationTests.m @@ -42,7 +42,7 @@ FSTDocument *baseDoc = FSTTestDoc(@"collection/key", 0, docData, NO); FSTMutation *set = FSTTestSetMutation(@"collection/key", @{@"bar" : @"bar-value"}); - FSTMaybeDocument *setDoc = [set applyTo:baseDoc baseDoc:baseDoc localWriteTime:_timestamp]; + FSTMaybeDocument *setDoc = [set applyTo:baseDoc baseDocument:baseDoc localWriteTime:_timestamp]; NSDictionary *expectedData = @{@"bar" : @"bar-value"}; XCTAssertEqualObjects(setDoc, FSTTestDoc(@"collection/key", 0, expectedData, YES)); @@ -54,7 +54,8 @@ FSTMutation *patch = FSTTestPatchMutation(@"collection/key", @{@"foo.bar" : @"new-bar-value"}, nil); - FSTMaybeDocument *patchedDoc = [patch applyTo:baseDoc baseDoc:baseDoc localWriteTime:_timestamp]; + FSTMaybeDocument *patchedDoc = + [patch applyTo:baseDoc baseDocument:baseDoc localWriteTime:_timestamp]; NSDictionary *expectedData = @{ @"foo" : @{@"bar" : @"new-bar-value"}, @"baz" : @"baz-value" }; XCTAssertEqualObjects(patchedDoc, FSTTestDoc(@"collection/key", 0, expectedData, YES)); @@ -70,7 +71,8 @@ fieldMask:mask value:[FSTObjectValue objectValue] precondition:[FSTPrecondition none]]; - FSTMaybeDocument *patchedDoc = [patch applyTo:baseDoc baseDoc:baseDoc localWriteTime:_timestamp]; + FSTMaybeDocument *patchedDoc = + [patch applyTo:baseDoc baseDocument:baseDoc localWriteTime:_timestamp]; NSDictionary *expectedData = @{ @"foo" : @{@"baz" : @"baz-value"} }; XCTAssertEqualObjects(patchedDoc, FSTTestDoc(@"collection/key", 0, expectedData, YES)); @@ -82,7 +84,8 @@ FSTMutation *patch = FSTTestPatchMutation(@"collection/key", @{@"foo.bar" : @"new-bar-value"}, nil); - FSTMaybeDocument *patchedDoc = [patch applyTo:baseDoc baseDoc:baseDoc localWriteTime:_timestamp]; + FSTMaybeDocument *patchedDoc = + [patch applyTo:baseDoc baseDocument:baseDoc localWriteTime:_timestamp]; NSDictionary *expectedData = @{ @"foo" : @{@"bar" : @"new-bar-value"}, @"baz" : @"baz-value" }; XCTAssertEqualObjects(patchedDoc, FSTTestDoc(@"collection/key", 0, expectedData, YES)); @@ -91,7 +94,8 @@ - (void)testPatchingDeletedDocumentsDoesNothing { FSTMaybeDocument *baseDoc = FSTTestDeletedDoc(@"collection/key", 0); FSTMutation *patch = FSTTestPatchMutation(@"collection/key", @{@"foo" : @"bar"}, nil); - FSTMaybeDocument *patchedDoc = [patch applyTo:baseDoc baseDoc:baseDoc localWriteTime:_timestamp]; + FSTMaybeDocument *patchedDoc = + [patch applyTo:baseDoc baseDocument:baseDoc localWriteTime:_timestamp]; XCTAssertEqualObjects(patchedDoc, baseDoc); } @@ -101,7 +105,7 @@ FSTMutation *transform = FSTTestTransformMutation(@"collection/key", @[ @"foo.bar" ]); FSTMaybeDocument *transformedDoc = - [transform applyTo:baseDoc baseDoc:baseDoc localWriteTime:_timestamp]; + [transform applyTo:baseDoc baseDocument:baseDoc localWriteTime:_timestamp]; // Server timestamps aren't parsed, so we manually insert it. FSTObjectValue *expectedData = FSTTestObjectValue( @@ -132,7 +136,7 @@ transformResults:@[ [FSTTimestampValue timestampValue:_timestamp] ]]; FSTMaybeDocument *transformedDoc = [transform applyTo:baseDoc - baseDoc:baseDoc + baseDocument:baseDoc localWriteTime:_timestamp mutationResult:mutationResult]; @@ -147,7 +151,8 @@ FSTDocument *baseDoc = FSTTestDoc(@"collection/key", 0, docData, NO); FSTMutation *mutation = FSTTestDeleteMutation(@"collection/key"); - FSTMaybeDocument *result = [mutation applyTo:baseDoc baseDoc:baseDoc localWriteTime:_timestamp]; + FSTMaybeDocument *result = + [mutation applyTo:baseDoc baseDocument:baseDoc localWriteTime:_timestamp]; XCTAssertEqualObjects(result, FSTTestDeletedDoc(@"collection/key", 0)); } @@ -158,8 +163,10 @@ FSTMutation *set = FSTTestSetMutation(@"collection/key", @{@"foo" : @"new-bar"}); FSTMutationResult *mutationResult = [[FSTMutationResult alloc] initWithVersion:FSTTestVersion(4) transformResults:nil]; - FSTMaybeDocument *setDoc = - [set applyTo:baseDoc baseDoc:baseDoc localWriteTime:_timestamp mutationResult:mutationResult]; + FSTMaybeDocument *setDoc = [set applyTo:baseDoc + baseDocument:baseDoc + localWriteTime:_timestamp + mutationResult:mutationResult]; NSDictionary *expectedData = @{@"foo" : @"new-bar"}; XCTAssertEqualObjects(setDoc, FSTTestDoc(@"collection/key", 0, expectedData, NO)); @@ -173,7 +180,7 @@ FSTMutationResult *mutationResult = [[FSTMutationResult alloc] initWithVersion:FSTTestVersion(4) transformResults:nil]; FSTMaybeDocument *patchedDoc = [patch applyTo:baseDoc - baseDoc:baseDoc + baseDocument:baseDoc localWriteTime:_timestamp mutationResult:mutationResult]; @@ -186,7 +193,7 @@ FSTMutationResult *mutationResult = \ [[FSTMutationResult alloc] initWithVersion:FSTTestVersion(0) transformResults:nil]; \ FSTMaybeDocument *actual = [mutation applyTo:base \ - baseDoc:base \ + baseDocument:base \ localWriteTime:_timestamp \ mutationResult:mutationResult]; \ XCTAssertEqualObjects(actual, expected); \ diff --git a/Firestore/Source/API/FIRDocumentSnapshot.m b/Firestore/Source/API/FIRDocumentSnapshot.m index 0d60033..e4e75c6 100644 --- a/Firestore/Source/API/FIRDocumentSnapshot.m +++ b/Firestore/Source/API/FIRDocumentSnapshot.m @@ -116,7 +116,7 @@ NS_ASSUME_NONNULL_BEGIN } return [self convertedObject:[self.internalDocument data] - options:[self convertedSnapshotOptions:options]]; + options:[FSTFieldValueOptions fieldValueOptions:options]]; } - (nullable id)valueForField:(id)field { @@ -135,7 +135,7 @@ NS_ASSUME_NONNULL_BEGIN } FSTFieldValue *fieldValue = [[self.internalDocument data] valueForPath:fieldPath.internalValue]; - return [self convertedValue:fieldValue options:[self convertedSnapshotOptions:options]]; + return [self convertedValue:fieldValue options:[FSTFieldValueOptions fieldValueOptions:options]]; } - (nullable id)objectForKeyedSubscript:(id)key { @@ -187,20 +187,6 @@ NS_ASSUME_NONNULL_BEGIN return result; } -/** Create a field value option from a snapshot option. */ -- (FSTFieldValueOptions *)convertedSnapshotOptions:(FIRSnapshotOptions *)snapshotOptions { - switch (snapshotOptions.serverTimestampBehavior) { - case FIRServerTimestampBehaviorEstimate: - return [[FSTFieldValueOptions alloc] - initWithServerTimestampBehavior:FSTServerTimestampBehaviorEstimate]; - case FIRServerTimestampBehaviorPrevious: - return [[FSTFieldValueOptions alloc] - initWithServerTimestampBehavior:FSTServerTimestampBehaviorPrevious]; - default: - return [FSTFieldValueOptions defaultOptions]; - } -} - @end NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/API/FIRSnapshotOptions+Internal.h b/Firestore/Source/API/FIRSnapshotOptions+Internal.h index de2aaa7..64e7dbc 100644 --- a/Firestore/Source/API/FIRSnapshotOptions+Internal.h +++ b/Firestore/Source/API/FIRSnapshotOptions+Internal.h @@ -18,7 +18,7 @@ #import <Foundation/Foundation.h> -@class FIRSnapshotOptions; +#import "Firestore/Source/Model/FSTFieldValue.h" NS_ASSUME_NONNULL_BEGIN @@ -28,10 +28,10 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)defaultOptions; /* Initializes a new instance with the specified server timestamp behavior. */ -- (instancetype)initWithServerTimestampBehavior:(int)serverTimestampBehavior; +- (instancetype)initWithServerTimestampBehavior:(FSTServerTimestampBehavior)serverTimestampBehavior; /* Returns the server timestamp behavior. Returns -1 if no behavior is specified. */ -- (int)serverTimestampBehavior; +- (FSTServerTimestampBehavior)serverTimestampBehavior; @end diff --git a/Firestore/Source/API/FIRSnapshotOptions.m b/Firestore/Source/API/FIRSnapshotOptions.m index adc4a65..71d9d51 100644 --- a/Firestore/Source/API/FIRSnapshotOptions.m +++ b/Firestore/Source/API/FIRSnapshotOptions.m @@ -16,34 +16,20 @@ #import "FIRDocumentSnapshot.h" -#import "FIRDocumentSnapshot+Internal.h" -#import "FSTAssert.h" -#import "Firestore/Source/API/FIRDocumentReference+Internal.h" -#import "Firestore/Source/API/FIRFieldPath+Internal.h" -#import "Firestore/Source/API/FIRFirestore+Internal.h" -#import "Firestore/Source/API/FIRSnapshotMetadata+Internal.h" #import "Firestore/Source/API/FIRSnapshotOptions+Internal.h" -#import "Firestore/Source/Model/FSTDatabaseID.h" -#import "Firestore/Source/Model/FSTDocument.h" -#import "Firestore/Source/Model/FSTDocumentKey.h" -#import "Firestore/Source/Model/FSTFieldValue.h" -#import "Firestore/Source/Model/FSTPath.h" -#import "Firestore/Source/Util/FSTUsageValidation.h" +#import "Firestore/Source/Util/FSTAssert.h" NS_ASSUME_NONNULL_BEGIN -/** The default server timestamp behavior (returning NSNull for pending timestamps). */ -static const int kFIRServerTimestampBehaviorDefault = -1; - @interface FIRSnapshotOptions () -@property(nonatomic) int serverTimestampBehavior; +@property(nonatomic) FSTServerTimestampBehavior serverTimestampBehavior; @end @implementation FIRSnapshotOptions -- (instancetype)initWithServerTimestampBehavior:(int)serverTimestampBehavior { +- (instancetype)initWithServerTimestampBehavior:(FSTServerTimestampBehavior)serverTimestampBehavior { self = [super init]; if (self) { @@ -59,20 +45,20 @@ static const int kFIRServerTimestampBehaviorDefault = -1; dispatch_once(&onceToken, ^{ sharedInstance = [[FIRSnapshotOptions alloc] - initWithServerTimestampBehavior:kFIRServerTimestampBehaviorDefault]; + initWithServerTimestampBehavior:FSTServerTimestampBehaviorDefault]; }); return sharedInstance; } -+ (instancetype)setServerTimestampBehavior:(FIRServerTimestampBehavior)serverTimestampBehavior { ++ (instancetype)serverTimestampBehavior:(FIRServerTimestampBehavior)serverTimestampBehavior { switch (serverTimestampBehavior) { case FIRServerTimestampBehaviorEstimate: return [[FIRSnapshotOptions alloc] - initWithServerTimestampBehavior:FIRServerTimestampBehaviorEstimate]; + initWithServerTimestampBehavior:FSTServerTimestampBehaviorEstimate]; case FIRServerTimestampBehaviorPrevious: return [[FIRSnapshotOptions alloc] - initWithServerTimestampBehavior:FIRServerTimestampBehaviorPrevious]; + initWithServerTimestampBehavior:FSTServerTimestampBehaviorPrevious]; default: FSTFail(@"Encountered unknown server timestamp behavior: %d", (int)serverTimestampBehavior); } diff --git a/Firestore/Source/Model/FSTFieldValue.h b/Firestore/Source/Model/FSTFieldValue.h index 969b3b0..f13f93f 100644 --- a/Firestore/Source/Model/FSTFieldValue.h +++ b/Firestore/Source/Model/FSTFieldValue.h @@ -24,6 +24,7 @@ @class FSTTimestamp; @class FSTFieldValueOptions; @class FIRGeoPoint; +@class FIRSnapshotOptions; NS_ASSUME_NONNULL_BEGIN @@ -51,17 +52,19 @@ typedef NS_ENUM(NSInteger, FSTServerTimestampBehavior) { /** Holds properties that define field value deserialization options. */ @interface FSTFieldValueOptions : NSObject -@property(nonatomic, readonly) FSTServerTimestampBehavior serverTimestampBehavior; +@property(nonatomic, readonly, assign) FSTServerTimestampBehavior serverTimestampBehavior; - (instancetype)init NS_UNAVAILABLE; -/** Creates a FSTFieldValueOptions instance that specifies deserialization behavior for pending - * server timestamps. */ +/** + * Creates a FSTFieldValueOptions instance that specifies deserialization behavior for pending + * server timestamps. + */ - (instancetype)initWithServerTimestampBehavior:(FSTServerTimestampBehavior)serverTimestampBehavior NS_DESIGNATED_INITIALIZER; -/** Returns the default deserialization options. */ -+ (instancetype)defaultOptions; +/** Creates FSTFieldValueOptions from FIRSnapshotOptions. */ ++ (instancetype)fieldValueOptions:(FIRSnapshotOptions *)value; @end @@ -114,7 +117,7 @@ typedef NS_ENUM(NSInteger, FSTServerTimestampBehavior) { */ @interface FSTNullValue : FSTFieldValue + (instancetype)nullValue; -- (id)valueWithOptions:(FSTFieldValueOptions *)options; +- (NSNull *)valueWithOptions:(FSTFieldValueOptions *)options; @end /** diff --git a/Firestore/Source/Model/FSTFieldValue.m b/Firestore/Source/Model/FSTFieldValue.m index 65478ce..91d6c43 100644 --- a/Firestore/Source/Model/FSTFieldValue.m +++ b/Firestore/Source/Model/FSTFieldValue.m @@ -17,6 +17,7 @@ #import "Firestore/Source/Model/FSTFieldValue.h" #import "Firestore/Source/API/FIRGeoPoint+Internal.h" +#import "Firestore/Source/API/FIRSnapshotOptions+Internal.h" #import "Firestore/Source/Core/FSTTimestamp.h" #import "Firestore/Source/Model/FSTDatabaseID.h" #import "Firestore/Source/Model/FSTDocumentKey.h" @@ -31,6 +32,22 @@ NS_ASSUME_NONNULL_BEGIN @implementation FSTFieldValueOptions ++ (instancetype)fieldValueOptions:(FIRSnapshotOptions *)options { + if (options.serverTimestampBehavior == FSTServerTimestampBehaviorDefault) { + static FSTFieldValueOptions *defaultInstance = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + defaultInstance = [[FSTFieldValueOptions alloc] + initWithServerTimestampBehavior:FSTServerTimestampBehaviorDefault]; + }); + return defaultInstance; + } else { + return [[FSTFieldValueOptions alloc] + initWithServerTimestampBehavior:options.serverTimestampBehavior]; + } +} + - (instancetype)initWithServerTimestampBehavior: (FSTServerTimestampBehavior)serverTimestampBehavior { self = [super init]; @@ -41,18 +58,6 @@ NS_ASSUME_NONNULL_BEGIN return self; } -+ (instancetype)defaultOptions { - static FSTFieldValueOptions *sharedInstance = nil; - static dispatch_once_t onceToken; - - dispatch_once(&onceToken, ^{ - sharedInstance = [[FSTFieldValueOptions alloc] - initWithServerTimestampBehavior:FSTServerTimestampBehaviorDefault]; - }); - - return sharedInstance; -} - @end #pragma mark - FSTFieldValue @@ -68,7 +73,8 @@ NS_ASSUME_NONNULL_BEGIN } - (id)value { - return [self valueWithOptions:[FSTFieldValueOptions defaultOptions]]; + return [self valueWithOptions:[FSTFieldValueOptions + fieldValueOptions:[FIRSnapshotOptions defaultOptions]]]; } - (id)valueWithOptions:(FSTFieldValueOptions *)options { diff --git a/Firestore/Source/Model/FSTMutation.h b/Firestore/Source/Model/FSTMutation.h index b2e7f5e..7c5f6de 100644 --- a/Firestore/Source/Model/FSTMutation.h +++ b/Firestore/Source/Model/FSTMutation.h @@ -198,18 +198,18 @@ typedef NS_ENUM(NSUInteger, FSTPreconditionExists) { * apply the transform if the prior mutation resulted in an FSTDocument (always true for an * FSTSetMutation, but not necessarily for an FSTPatchMutation). */ -- (FSTMaybeDocument *_Nullable)applyTo:(FSTMaybeDocument *_Nullable)maybeDoc - baseDoc:(FSTMaybeDocument *_Nullable)baseDoc +- (nullable FSTMaybeDocument *)applyTo:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc localWriteTime:(FSTTimestamp *)localWriteTime - mutationResult:(FSTMutationResult *_Nullable)mutationResult; + mutationResult:(nullable FSTMutationResult *)mutationResult; /** * A helper version of applyTo for applying mutations locally (without a mutation result from the * backend). */ -- (FSTMaybeDocument *_Nullable)applyTo:(FSTMaybeDocument *_Nullable)maybeDoc - baseDoc:(FSTMaybeDocument *_Nullable)baseDoc - localWriteTime:(FSTTimestamp *)localWriteTime; +- (nullable FSTMaybeDocument *)applyTo:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc + localWriteTime:(nullable FSTTimestamp *)localWriteTime; @property(nonatomic, strong, readonly) FSTDocumentKey *key; diff --git a/Firestore/Source/Model/FSTMutation.m b/Firestore/Source/Model/FSTMutation.m index 2685990..375e289 100644 --- a/Firestore/Source/Model/FSTMutation.m +++ b/Firestore/Source/Model/FSTMutation.m @@ -236,17 +236,18 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (FSTMaybeDocument *_Nullable)applyTo:(FSTMaybeDocument *_Nullable)maybeDoc - baseDoc:(FSTMaybeDocument *_Nullable)baseDoc +- (nullable FSTMaybeDocument *)applyTo:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc localWriteTime:(FSTTimestamp *)localWriteTime - mutationResult:(FSTMutationResult *_Nullable)mutationResult { + mutationResult:(nullable FSTMutationResult *)mutationResult { @throw FSTAbstractMethodException(); // NOLINT } -- (FSTMaybeDocument *_Nullable)applyTo:(FSTMaybeDocument *_Nullable)maybeDoc - baseDoc:(FSTMaybeDocument *_Nullable)baseDoc - localWriteTime:(FSTTimestamp *)localWriteTime { - return [self applyTo:maybeDoc baseDoc:baseDoc localWriteTime:localWriteTime mutationResult:nil]; +- (nullable FSTMaybeDocument *)applyTo:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc + localWriteTime:(nullable FSTTimestamp *)localWriteTime { + return + [self applyTo:maybeDoc baseDocument:baseDoc localWriteTime:localWriteTime mutationResult:nil]; } @end @@ -289,10 +290,10 @@ NS_ASSUME_NONNULL_BEGIN return result; } -- (FSTMaybeDocument *_Nullable)applyTo:(FSTMaybeDocument *_Nullable)maybeDoc - baseDoc:(FSTMaybeDocument *_Nullable)baseDoc +- (nullable FSTMaybeDocument *)applyTo:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc localWriteTime:(FSTTimestamp *)localWriteTime - mutationResult:(FSTMutationResult *_Nullable)mutationResult { + mutationResult:(nullable FSTMutationResult *)mutationResult { if (mutationResult) { FSTAssert(!mutationResult.transformResults, @"Transform results received by FSTSetMutation."); } @@ -365,10 +366,10 @@ NS_ASSUME_NONNULL_BEGIN self.key, self.fieldMask, self.value, self.precondition]; } -- (FSTMaybeDocument *_Nullable)applyTo:(FSTMaybeDocument *_Nullable)maybeDoc - baseDoc:(FSTMaybeDocument *_Nullable)baseDoc +- (nullable FSTMaybeDocument *)applyTo:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc localWriteTime:(FSTTimestamp *)localWriteTime - mutationResult:(FSTMutationResult *_Nullable)mutationResult { + mutationResult:(nullable FSTMutationResult *)mutationResult { if (mutationResult) { FSTAssert(!mutationResult.transformResults, @"Transform results received by FSTPatchMutation."); } @@ -455,10 +456,10 @@ NS_ASSUME_NONNULL_BEGIN self.key, self.fieldTransforms, self.precondition]; } -- (FSTMaybeDocument *_Nullable)applyTo:(FSTMaybeDocument *_Nullable)maybeDoc - baseDoc:(FSTMaybeDocument *_Nullable)baseDoc +- (nullable FSTMaybeDocument *)applyTo:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc localWriteTime:(FSTTimestamp *)localWriteTime - mutationResult:(FSTMutationResult *_Nullable)mutationResult { + mutationResult:(nullable FSTMutationResult *)mutationResult { if (mutationResult) { FSTAssert(mutationResult.transformResults, @"Transform results missing for FSTTransformMutation."); @@ -480,7 +481,7 @@ NS_ASSUME_NONNULL_BEGIN NSArray<FSTFieldValue *> *transformResults = mutationResult ? mutationResult.transformResults - : [self localTransformResultsWithPreviousDocument:baseDoc writeTime:localWriteTime]; + : [self localTransformResultsWithBaseDocument:baseDoc writeTime:localWriteTime]; FSTObjectValue *newData = [self transformObject:doc.data transformResults:transformResults]; return [FSTDocument documentWithData:newData key:doc.key @@ -492,21 +493,21 @@ NS_ASSUME_NONNULL_BEGIN * Creates an array of "transform results" (a transform result is a field value representing the * result of applying a transform) for use when applying an FSTTransformMutation locally. * - * @param previousDocument The document prior to applying this mutation batch. + * @param baseDocument The document prior to applying this mutation batch. * @param localWriteTime The local time of the transform mutation (used to generate * FSTServerTimestampValues). * @return The transform results array. */ -- (NSArray<FSTFieldValue *> *) -localTransformResultsWithPreviousDocument:(FSTMaybeDocument *_Nullable)previousDocument - writeTime:(FSTTimestamp *)localWriteTime { +- (NSArray<FSTFieldValue *> *)localTransformResultsWithBaseDocument: + (FSTMaybeDocument *_Nullable)baseDocument + writeTime:(FSTTimestamp *)localWriteTime { NSMutableArray<FSTFieldValue *> *transformResults = [NSMutableArray array]; for (FSTFieldTransform *fieldTransform in self.fieldTransforms) { if ([fieldTransform.transform isKindOfClass:[FSTServerTimestampTransform class]]) { FSTFieldValue *previousValue = nil; - if (previousDocument && [previousDocument isMemberOfClass:[FSTDocument class]]) { - previousValue = [((FSTDocument *)previousDocument) fieldForPath:fieldTransform.path]; + if ([baseDocument isMemberOfClass:[FSTDocument class]]) { + previousValue = [((FSTDocument *)baseDocument) fieldForPath:fieldTransform.path]; } [transformResults @@ -567,10 +568,10 @@ localTransformResultsWithPreviousDocument:(FSTMaybeDocument *_Nullable)previousD stringWithFormat:@"<FSTDeleteMutation key=%@ precondition=%@>", self.key, self.precondition]; } -- (FSTMaybeDocument *_Nullable)applyTo:(FSTMaybeDocument *_Nullable)maybeDoc - baseDoc:(FSTMaybeDocument *_Nullable)baseDoc +- (nullable FSTMaybeDocument *)applyTo:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc localWriteTime:(FSTTimestamp *)localWriteTime - mutationResult:(FSTMutationResult *_Nullable)mutationResult { + mutationResult:(nullable FSTMutationResult *)mutationResult { if (mutationResult) { FSTAssert(!mutationResult.transformResults, @"Transform results received by FSTDeleteMutation."); diff --git a/Firestore/Source/Model/FSTMutationBatch.m b/Firestore/Source/Model/FSTMutationBatch.m index 1d16de5..01adca7 100644 --- a/Firestore/Source/Model/FSTMutationBatch.m +++ b/Firestore/Source/Model/FSTMutationBatch.m @@ -84,7 +84,7 @@ const FSTBatchID kFSTBatchIDUnknown = -1; FSTMutationResult *_Nullable mutationResult = mutationBatchResult.mutationResults[i]; if ([mutation.key isEqualToKey:documentKey]) { maybeDoc = [mutation applyTo:maybeDoc - baseDoc:baseDoc + baseDocument:baseDoc localWriteTime:self.localWriteTime mutationResult:mutationResult]; } diff --git a/Firestore/Source/Public/FIRDocumentSnapshot.h b/Firestore/Source/Public/FIRDocumentSnapshot.h index f1ae6d8..0b72fe4 100644 --- a/Firestore/Source/Public/FIRDocumentSnapshot.h +++ b/Firestore/Source/Public/FIRDocumentSnapshot.h @@ -60,7 +60,7 @@ NS_SWIFT_NAME(SnapshotOptions) * * @return The created `FIRSnapshotOptions` object. */ -+ (instancetype)setServerTimestampBehavior:(FIRServerTimestampBehavior)serverTimestampBehavior; ++ (instancetype)serverTimestampBehavior:(FIRServerTimestampBehavior)serverTimestampBehavior; @end @@ -103,8 +103,8 @@ NS_SWIFT_NAME(DocumentSnapshot) * Retrieves all fields in the document as a `Dictionary`. * * @param options `SnapshotOptions` to configure how data is returned from - * the snapshot (e.g. the desired behavior for server timestamps that have not - * yet been set to their final value). + * the snapshot (e.g. the desired behavior for server timestamps that have not + * yet been set to their final value). * @return A `Dictionary` containing all fields in the document. */ - (NSDictionary<NSString *, id> *)dataWithOptions:(FIRSnapshotOptions *)options; @@ -130,8 +130,8 @@ NS_SWIFT_NAME(DocumentSnapshot) * * @param field The field to retrieve. * @param options `SnapshotOptions` to configure how data is returned from - * the snapshot (e.g. the desired behavior for server timestamps that have not - * yet been set to their final value). + * the snapshot (e.g. the desired behavior for server timestamps that have not + * yet been set to their final value). * @return The value contained in the field or `nil` if the field doesn't exist. */ // clang-format off |