aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar zxu <zxu@google.com>2018-02-15 17:23:08 -0500
committerGravatar GitHub <noreply@github.com>2018-02-15 17:23:08 -0500
commitfd9fd271d0dba3935a6f5611a1554f2c59b696af (patch)
treebe6d8355254891cb83201c7bfac2082c0f95978f
parent6889850b251ab56186bc13765baee0c3d0f1ae61 (diff)
replacing Auth/FSTUser by C++ auth implementation (#804)
* replacing Auth/FSTUser by C++ auth implementation * address changes
-rw-r--r--Firestore/Example/Tests/Local/FSTLevelDBLocalStoreTests.mm1
-rw-r--r--Firestore/Example/Tests/Local/FSTLevelDBMutationQueueTests.mm5
-rw-r--r--Firestore/Example/Tests/Local/FSTLocalStoreTests.mm9
-rw-r--r--Firestore/Example/Tests/Local/FSTMemoryMutationQueueTests.mm8
-rw-r--r--Firestore/Example/Tests/Local/FSTMutationQueueTests.mm8
-rw-r--r--Firestore/Example/Tests/SpecTests/FSTSpecTests.mm21
-rw-r--r--Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.h20
-rw-r--r--Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm50
-rw-r--r--Firestore/Source/API/FIRFirestore.mm2
-rw-r--r--Firestore/Source/Auth/FSTCredentialsProvider.h13
-rw-r--r--Firestore/Source/Auth/FSTCredentialsProvider.mm43
-rw-r--r--Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm7
-rw-r--r--Firestore/Source/Auth/FSTUser.h43
-rw-r--r--Firestore/Source/Auth/FSTUser.mm68
-rw-r--r--Firestore/Source/Core/FSTFirestoreClient.mm16
-rw-r--r--Firestore/Source/Core/FSTSyncEngine.h8
-rw-r--r--Firestore/Source/Core/FSTSyncEngine.mm32
-rw-r--r--Firestore/Source/Local/FSTLevelDB.mm4
-rw-r--r--Firestore/Source/Local/FSTLevelDBMutationQueue.h5
-rw-r--r--Firestore/Source/Local/FSTLevelDBMutationQueue.mm9
-rw-r--r--Firestore/Source/Local/FSTLocalStore.h8
-rw-r--r--Firestore/Source/Local/FSTLocalStore.mm7
-rw-r--r--Firestore/Source/Local/FSTMemoryPersistence.mm19
-rw-r--r--Firestore/Source/Local/FSTPersistence.h5
-rw-r--r--Firestore/Source/Remote/FSTRemoteStore.h5
-rw-r--r--Firestore/Source/Remote/FSTRemoteStore.mm11
-rw-r--r--Firestore/core/src/firebase/firestore/auth/user.h19
-rw-r--r--Firestore/core/test/firebase/firestore/auth/user_test.cc5
28 files changed, 221 insertions, 230 deletions
diff --git a/Firestore/Example/Tests/Local/FSTLevelDBLocalStoreTests.mm b/Firestore/Example/Tests/Local/FSTLevelDBLocalStoreTests.mm
index f71f5c9..97e3c5b 100644
--- a/Firestore/Example/Tests/Local/FSTLevelDBLocalStoreTests.mm
+++ b/Firestore/Example/Tests/Local/FSTLevelDBLocalStoreTests.mm
@@ -18,7 +18,6 @@
#import <XCTest/XCTest.h>
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Local/FSTLevelDB.h"
#import "Firestore/Example/Tests/Local/FSTLocalStoreTests.h"
diff --git a/Firestore/Example/Tests/Local/FSTLevelDBMutationQueueTests.mm b/Firestore/Example/Tests/Local/FSTLevelDBMutationQueueTests.mm
index fe79598..2e24055 100644
--- a/Firestore/Example/Tests/Local/FSTLevelDBMutationQueueTests.mm
+++ b/Firestore/Example/Tests/Local/FSTLevelDBMutationQueueTests.mm
@@ -20,7 +20,6 @@
#include <leveldb/db.h>
#import "Firestore/Protos/objc/firestore/local/Mutation.pbobjc.h"
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Local/FSTLevelDB.h"
#import "Firestore/Source/Local/FSTLevelDBKey.h"
#import "Firestore/Source/Local/FSTWriteGroup.h"
@@ -28,6 +27,7 @@
#import "Firestore/Example/Tests/Local/FSTMutationQueueTests.h"
#import "Firestore/Example/Tests/Local/FSTPersistenceTestHelpers.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
#include "Firestore/core/src/firebase/firestore/util/ordered_code.h"
NS_ASSUME_NONNULL_BEGIN
@@ -37,6 +37,7 @@ using leveldb::Slice;
using leveldb::Status;
using leveldb::WriteOptions;
using Firestore::StringView;
+using firebase::firestore::auth::User;
using firebase::firestore::util::OrderedCode;
// A dummy mutation value, useful for testing code that's known to examine only mutation keys.
@@ -69,7 +70,7 @@ std::string MutationLikeKey(StringView table, StringView userID, FSTBatchID batc
- (void)setUp {
[super setUp];
_db = [FSTPersistenceTestHelpers levelDBPersistence];
- self.mutationQueue = [_db mutationQueueForUser:[[FSTUser alloc] initWithUID:@"user"]];
+ self.mutationQueue = [_db mutationQueueForUser:User("user")];
self.persistence = _db;
FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Start MutationQueue"];
diff --git a/Firestore/Example/Tests/Local/FSTLocalStoreTests.mm b/Firestore/Example/Tests/Local/FSTLocalStoreTests.mm
index 45d1815..f3493ce 100644
--- a/Firestore/Example/Tests/Local/FSTLocalStoreTests.mm
+++ b/Firestore/Example/Tests/Local/FSTLocalStoreTests.mm
@@ -18,7 +18,6 @@
#import <XCTest/XCTest.h>
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Core/FSTQuery.h"
#import "Firestore/Source/Core/FSTTimestamp.h"
#import "Firestore/Source/Local/FSTEagerGarbageCollector.h"
@@ -42,6 +41,10 @@
#import "Firestore/third_party/Immutable/Tests/FSTImmutableSortedDictionary+Testing.h"
#import "Firestore/third_party/Immutable/Tests/FSTImmutableSortedSet+Testing.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
+using firebase::firestore::auth::User;
+
NS_ASSUME_NONNULL_BEGIN
/** Creates a document version dictionary mapping the document in @a mutation to @a version. */
@@ -77,7 +80,7 @@ FSTDocumentVersionDictionary *FSTVersionDictionary(FSTMutation *mutation,
id<FSTGarbageCollector> garbageCollector = [[FSTEagerGarbageCollector alloc] init];
self.localStore = [[FSTLocalStore alloc] initWithPersistence:persistence
garbageCollector:garbageCollector
- initialUser:[FSTUser unauthenticatedUser]];
+ initialUser:User::Unauthenticated()];
[self.localStore start];
_batches = [NSMutableArray array];
@@ -112,7 +115,7 @@ FSTDocumentVersionDictionary *FSTVersionDictionary(FSTMutation *mutation,
id<FSTGarbageCollector> garbageCollector = [[FSTNoOpGarbageCollector alloc] init];
self.localStore = [[FSTLocalStore alloc] initWithPersistence:self.localStorePersistence
garbageCollector:garbageCollector
- initialUser:[FSTUser unauthenticatedUser]];
+ initialUser:User::Unauthenticated()];
[self.localStore start];
}
diff --git a/Firestore/Example/Tests/Local/FSTMemoryMutationQueueTests.mm b/Firestore/Example/Tests/Local/FSTMemoryMutationQueueTests.mm
index ab7afee..5567078 100644
--- a/Firestore/Example/Tests/Local/FSTMemoryMutationQueueTests.mm
+++ b/Firestore/Example/Tests/Local/FSTMemoryMutationQueueTests.mm
@@ -16,12 +16,15 @@
#import "Firestore/Source/Local/FSTMemoryMutationQueue.h"
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Local/FSTMemoryPersistence.h"
#import "Firestore/Example/Tests/Local/FSTMutationQueueTests.h"
#import "Firestore/Example/Tests/Local/FSTPersistenceTestHelpers.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
+using firebase::firestore::auth::User;
+
@interface FSTMemoryMutationQueueTests : FSTMutationQueueTests
@end
@@ -35,8 +38,7 @@
[super setUp];
self.persistence = [FSTPersistenceTestHelpers memoryPersistence];
- self.mutationQueue =
- [self.persistence mutationQueueForUser:[[FSTUser alloc] initWithUID:@"user"]];
+ self.mutationQueue = [self.persistence mutationQueueForUser:User("user")];
}
@end
diff --git a/Firestore/Example/Tests/Local/FSTMutationQueueTests.mm b/Firestore/Example/Tests/Local/FSTMutationQueueTests.mm
index 020a0a7..62d30fb 100644
--- a/Firestore/Example/Tests/Local/FSTMutationQueueTests.mm
+++ b/Firestore/Example/Tests/Local/FSTMutationQueueTests.mm
@@ -16,7 +16,6 @@
#import "Firestore/Example/Tests/Local/FSTMutationQueueTests.h"
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Core/FSTQuery.h"
#import "Firestore/Source/Core/FSTTimestamp.h"
#import "Firestore/Source/Local/FSTEagerGarbageCollector.h"
@@ -28,6 +27,10 @@
#import "Firestore/Example/Tests/Util/FSTHelpers.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
+using firebase::firestore::auth::User;
+
NS_ASSUME_NONNULL_BEGIN
@implementation FSTMutationQueueTests
@@ -127,8 +130,7 @@ NS_ASSUME_NONNULL_BEGIN
// Restart the queue so that nextBatchID will be reset.
[self.mutationQueue shutdown];
- self.mutationQueue =
- [self.persistence mutationQueueForUser:[[FSTUser alloc] initWithUID:@"user"]];
+ self.mutationQueue = [self.persistence mutationQueueForUser:User("user")];
FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Start MutationQueue"];
[self.mutationQueue startWithGroup:group];
diff --git a/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm b/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm
index 3335990..87e3213 100644
--- a/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm
+++ b/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm
@@ -19,7 +19,6 @@
#import <FirebaseFirestore/FIRFirestoreErrors.h>
#import <GRPCClient/GRPCCall.h>
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Core/FSTEventManager.h"
#import "Firestore/Source/Core/FSTQuery.h"
#import "Firestore/Source/Core/FSTSnapshotVersion.h"
@@ -43,6 +42,12 @@
#import "Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.h"
#import "Firestore/Example/Tests/Util/FSTHelpers.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+
+namespace util = firebase::firestore::util;
+using firebase::firestore::auth::User;
+
NS_ASSUME_NONNULL_BEGIN
// Disables all other tests; useful for debugging. Multiple tests can have this tag and they'll all
@@ -327,15 +332,19 @@ static NSString *const kNoIOSTag = @"no-ios";
}
- (void)doChangeUser:(id)UID {
- FSTUser *user = [UID isEqual:[NSNull null]] ? [FSTUser unauthenticatedUser]
- : [[FSTUser alloc] initWithUID:UID];
- [self.driver changeUser:user];
+ if (UID == nil || [UID isEqual:[NSNull null]]) {
+ [self.driver changeUser:User::Unauthenticated()];
+ } else {
+ XCTAssert([UID isKindOfClass:[NSString class]]);
+ [self.driver changeUser:User(UID)];
+ }
}
- (void)doRestart {
// Any outstanding user writes should be automatically re-sent, so we want to preserve them
// when re-creating the driver.
- FSTOutstandingWriteQueues *outstandingWrites = self.driver.outstandingWrites;
+ FSTOutstandingWriteQueues outstandingWrites = self.driver.outstandingWrites;
+ User currentUser = self.driver.currentUser;
[self.driver shutdown];
@@ -347,7 +356,7 @@ static NSString *const kNoIOSTag = @"no-ios";
self.driver = [[FSTSyncEngineTestDriver alloc] initWithPersistence:self.driverPersistence
garbageCollector:self.garbageCollector
- initialUser:self.driver.currentUser
+ initialUser:currentUser
outstandingWrites:outstandingWrites];
[self.driver start];
}
diff --git a/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.h b/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.h
index 46601d7..466a347 100644
--- a/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.h
+++ b/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.h
@@ -16,16 +16,19 @@
#import <Foundation/Foundation.h>
+#include <unordered_map>
+
#import "Firestore/Source/Core/FSTTypes.h"
#import "Firestore/Source/Remote/FSTRemoteStore.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
@class FSTDocumentKey;
@class FSTMutation;
@class FSTMutationResult;
@class FSTQuery;
@class FSTQueryData;
@class FSTSnapshotVersion;
-@class FSTUser;
@class FSTViewSnapshot;
@class FSTWatchChange;
@protocol FSTGarbageCollector;
@@ -54,7 +57,10 @@ NS_ASSUME_NONNULL_BEGIN
@end
/** Mapping of user => array of FSTMutations for that user. */
-typedef NSDictionary<FSTUser *, NSArray<FSTOutstandingWrite *> *> FSTOutstandingWriteQueues;
+typedef std::unordered_map<firebase::firestore::auth::User,
+ NSMutableArray<FSTOutstandingWrite *> *,
+ firebase::firestore::auth::HashUser>
+ FSTOutstandingWriteQueues;
/**
* A test driver for FSTSyncEngine that allows simulated event delivery and capture. As much as
@@ -93,8 +99,8 @@ typedef NSDictionary<FSTUser *, NSArray<FSTOutstandingWrite *> *> FSTOutstanding
*/
- (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
garbageCollector:(id<FSTGarbageCollector>)garbageCollector
- initialUser:(FSTUser *)initialUser
- outstandingWrites:(FSTOutstandingWriteQueues *)outstandingWrites
+ initialUser:(const firebase::firestore::auth::User &)initialUser
+ outstandingWrites:(const FSTOutstandingWriteQueues &)outstandingWrites
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@@ -222,7 +228,7 @@ typedef NSDictionary<FSTUser *, NSArray<FSTOutstandingWrite *> *> FSTOutstanding
* each user, so future receiveWriteAck/Error operations will validate the write sent to the mock
* datastore matches the next outstanding write for that user.
*/
-- (void)changeUser:(FSTUser *)user;
+- (void)changeUser:(const firebase::firestore::auth::User &)user;
/**
* Returns all query events generated by the FSTSyncEngine in response to the event injection
@@ -246,10 +252,10 @@ typedef NSDictionary<FSTUser *, NSArray<FSTOutstandingWrite *> *> FSTOutstanding
* sentWritesCount, but not necessarily, since the FSTRemoteStore limits the number of
* outstanding writes to the backend at a given time.
*/
-@property(nonatomic, strong, readonly) FSTOutstandingWriteQueues *outstandingWrites;
+@property(nonatomic, assign, readonly) const FSTOutstandingWriteQueues &outstandingWrites;
/** The current user for the FSTSyncEngine; determines which mutation queue is active. */
-@property(nonatomic, strong, readonly) FSTUser *currentUser;
+@property(nonatomic, assign, readonly) const firebase::firestore::auth::User &currentUser;
/** The current set of documents in limbo. */
@property(nonatomic, strong, readonly)
diff --git a/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm b/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm
index a4de615..1c7eadf 100644
--- a/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm
+++ b/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm
@@ -16,10 +16,11 @@
#import "Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.h"
+#include <unordered_map>
+
#import <FirebaseFirestore/FIRFirestoreErrors.h>
#import <GRPCClient/GRPCCall.h>
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Core/FSTEventManager.h"
#import "Firestore/Source/Core/FSTQuery.h"
#import "Firestore/Source/Core/FSTSnapshotVersion.h"
@@ -36,6 +37,11 @@
#import "Firestore/Example/Tests/Core/FSTSyncEngine+Testing.h"
#import "Firestore/Example/Tests/SpecTests/FSTMockDatastore.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
+using firebase::firestore::auth::HashUser;
+using firebase::firestore::auth::User;
+
NS_ASSUME_NONNULL_BEGIN
@implementation FSTQueryEvent
@@ -71,35 +77,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, strong, readonly)
NSMutableDictionary<FSTQuery *, FSTQueryListener *> *queryListeners;
-#pragma mark - Other data structures.
-@property(nonatomic, strong, readwrite) FSTUser *currentUser;
-
@end
@implementation FSTSyncEngineTestDriver {
// ivar is declared as mutable.
- NSMutableDictionary<FSTUser *, NSMutableArray<FSTOutstandingWrite *> *> *_outstandingWrites;
+ std::unordered_map<User, NSMutableArray<FSTOutstandingWrite *> *, HashUser> _outstandingWrites;
+
+ User _currentUser;
}
- (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
garbageCollector:(id<FSTGarbageCollector>)garbageCollector {
return [self initWithPersistence:persistence
garbageCollector:garbageCollector
- initialUser:[FSTUser unauthenticatedUser]
- outstandingWrites:@{}];
+ initialUser:User::Unauthenticated()
+ outstandingWrites:{}];
}
- (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
garbageCollector:(id<FSTGarbageCollector>)garbageCollector
- initialUser:(FSTUser *)initialUser
- outstandingWrites:(FSTOutstandingWriteQueues *)outstandingWrites {
+ initialUser:(const User &)initialUser
+ outstandingWrites:(const FSTOutstandingWriteQueues &)outstandingWrites {
if (self = [super init]) {
- // Create mutable copy of outstandingWrites.
- _outstandingWrites = [NSMutableDictionary dictionary];
- [outstandingWrites enumerateKeysAndObjectsUsingBlock:^(
- FSTUser *user, NSArray<FSTOutstandingWrite *> *writes, BOOL *stop) {
- _outstandingWrites[user] = [writes mutableCopy];
- }];
+ // Do a deep copy.
+ for (const auto &pair : outstandingWrites) {
+ _outstandingWrites[pair.first] = [pair.second mutableCopy];
+ }
_events = [NSMutableArray array];
@@ -139,9 +142,12 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
-- (NSDictionary<FSTUser *, NSMutableArray<FSTOutstandingWrite *> *> *)outstandingWrites {
- return static_cast<NSDictionary<FSTUser *, NSMutableArray<FSTOutstandingWrite *> *> *>(
- _outstandingWrites);
+- (const FSTOutstandingWriteQueues &)outstandingWrites {
+ return _outstandingWrites;
+}
+
+- (const User &)currentUser {
+ return _currentUser;
}
- (void)applyChangedOnlineState:(FSTOnlineState)onlineState {
@@ -200,8 +206,8 @@ NS_ASSUME_NONNULL_BEGIN
[self.remoteStore enableNetwork];
}
-- (void)changeUser:(FSTUser *)user {
- self.currentUser = user;
+- (void)changeUser:(const User &)user {
+ _currentUser = user;
[self.syncEngine userDidChange:user];
}
@@ -309,10 +315,10 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Helper Methods
- (NSMutableArray<FSTOutstandingWrite *> *)currentOutstandingWrites {
- NSMutableArray<FSTOutstandingWrite *> *writes = _outstandingWrites[self.currentUser];
+ NSMutableArray<FSTOutstandingWrite *> *writes = _outstandingWrites[_currentUser];
if (!writes) {
writes = [NSMutableArray array];
- _outstandingWrites[self.currentUser] = writes;
+ _outstandingWrites[_currentUser] = writes;
}
return writes;
}
diff --git a/Firestore/Source/API/FIRFirestore.mm b/Firestore/Source/API/FIRFirestore.mm
index 5e978cc..6d2d27b 100644
--- a/Firestore/Source/API/FIRFirestore.mm
+++ b/Firestore/Source/API/FIRFirestore.mm
@@ -51,7 +51,7 @@ extern "C" NSString *const FIRFirestoreErrorDomain = @"FIRFirestoreErrorDomain";
@interface FIRFirestore () {
/** The actual owned DatabaseId instance is allocated in FIRFirestore. */
- firebase::firestore::model::DatabaseId _databaseID;
+ DatabaseId _databaseID;
}
@property(nonatomic, strong) NSString *persistenceKey;
diff --git a/Firestore/Source/Auth/FSTCredentialsProvider.h b/Firestore/Source/Auth/FSTCredentialsProvider.h
index 92d5fdc..230a22d 100644
--- a/Firestore/Source/Auth/FSTCredentialsProvider.h
+++ b/Firestore/Source/Auth/FSTCredentialsProvider.h
@@ -16,16 +16,17 @@
#import <Foundation/Foundation.h>
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
NS_ASSUME_NONNULL_BEGIN
@class FIRApp;
@class FSTDispatchQueue;
-@class FSTUser;
#pragma mark - FSTGetTokenResult
/**
- * The current FSTUser and the authentication token provided by the underlying authentication
+ * The current User and the authentication token provided by the underlying authentication
* mechanism. This is the result of calling -[FSTCredentialsProvider getTokenForcingRefresh].
*
* ## Portability notes: no TokenType on iOS
@@ -38,11 +39,11 @@ NS_ASSUME_NONNULL_BEGIN
@interface FSTGetTokenResult : NSObject
- (instancetype)init NS_UNAVAILABLE;
-- (instancetype)initWithUser:(FSTUser *)user
+- (instancetype)initWithUser:(const firebase::firestore::auth::User &)user
token:(NSString *_Nullable)token NS_DESIGNATED_INITIALIZER;
/** The user with which the token is associated (used for persisting user state on disk, etc.). */
-@property(nonatomic, nonnull, readonly) FSTUser *user;
+@property(nonatomic, assign, readonly) const firebase::firestore::auth::User &user;
/** The actual raw token. */
@property(nonatomic, copy, nullable, readonly) NSString *token;
@@ -60,8 +61,8 @@ NS_ASSUME_NONNULL_BEGIN
typedef void (^FSTVoidGetTokenResultBlock)(FSTGetTokenResult *_Nullable token,
NSError *_Nullable error);
-/** Listener block notified with an FSTUser. */
-typedef void (^FSTVoidUserBlock)(FSTUser *user);
+/** Listener block notified with a User. */
+typedef void (^FSTVoidUserBlock)(const firebase::firestore::auth::User &user);
#pragma mark - FSTCredentialsProvider
diff --git a/Firestore/Source/Auth/FSTCredentialsProvider.mm b/Firestore/Source/Auth/FSTCredentialsProvider.mm
index 653d7ff..cf045e3 100644
--- a/Firestore/Source/Auth/FSTCredentialsProvider.mm
+++ b/Firestore/Source/Auth/FSTCredentialsProvider.mm
@@ -21,36 +21,53 @@
#import <GRPCClient/GRPCCall.h>
#import "FIRFirestoreErrors.h"
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Util/FSTAssert.h"
#import "Firestore/Source/Util/FSTClasses.h"
#import "Firestore/Source/Util/FSTDispatchQueue.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+
+namespace util = firebase::firestore::util;
+using firebase::firestore::auth::User;
+
NS_ASSUME_NONNULL_BEGIN
#pragma mark - FSTGetTokenResult
+@interface FSTGetTokenResult () {
+ User _user;
+}
+
+@end
+
@implementation FSTGetTokenResult
-- (instancetype)initWithUser:(FSTUser *)user token:(NSString *_Nullable)token {
+
+- (instancetype)initWithUser:(const User &)user token:(NSString *_Nullable)token {
if (self = [super init]) {
_user = user;
_token = token;
}
return self;
}
+
+- (const User &)user {
+ return _user;
+}
+
@end
#pragma mark - FSTFirebaseCredentialsProvider
-@interface FSTFirebaseCredentialsProvider ()
+@interface FSTFirebaseCredentialsProvider () {
+ /** The current user as reported to us via our AuthStateDidChangeListener. */
+ User _currentUser;
+}
@property(nonatomic, strong, readonly) FIRApp *app;
/** Handle used to stop receiving auth changes once userChangeListener is removed. */
@property(nonatomic, strong, nullable, readwrite) id<NSObject> authListenerHandle;
-/** The current user as reported to us via our AuthStateDidChangeListener. */
-@property(nonatomic, strong, nonnull, readwrite) FSTUser *currentUser;
-
/**
* Counter used to detect if the user changed while a -getTokenForcingRefresh: request was
* outstanding.
@@ -67,7 +84,7 @@ NS_ASSUME_NONNULL_BEGIN
self = [super init];
if (self) {
_app = app;
- _currentUser = [[FSTUser alloc] initWithUID:[self.app getUID]];
+ _currentUser = User([self.app getUID]);
_userCounter = 0;
// Register for user changes so that we can internally track the current user.
@@ -90,13 +107,13 @@ NS_ASSUME_NONNULL_BEGIN
}
NSString *userID = userInfo[FIRAuthStateDidChangeInternalNotificationUIDKey];
- FSTUser *newUser = [[FSTUser alloc] initWithUID:userID];
- if (![newUser isEqual:self.currentUser]) {
- self.currentUser = newUser;
+ User newUser = User(userID);
+ if (newUser != _currentUser) {
+ _currentUser = newUser;
self.userCounter++;
FSTVoidUserBlock listenerBlock = self.userChangeListener;
if (listenerBlock) {
- listenerBlock(self.currentUser);
+ listenerBlock(_currentUser);
}
}
}
@@ -127,7 +144,7 @@ NS_ASSUME_NONNULL_BEGIN
completion(nil, cancelError);
} else {
FSTGetTokenResult *result =
- [[FSTGetTokenResult alloc] initWithUser:self.currentUser token:token];
+ [[FSTGetTokenResult alloc] initWithUser:_currentUser token:token];
completion(result, error);
}
};
@@ -142,7 +159,7 @@ NS_ASSUME_NONNULL_BEGIN
FSTAssert(!_userChangeListener, @"UserChangeListener set twice!");
// Fire initial event.
- block(self.currentUser);
+ block(_currentUser);
} else {
FSTAssert(self.authListenerHandle, @"UserChangeListener removed twice!");
FSTAssert(_userChangeListener, @"UserChangeListener removed without being set!");
diff --git a/Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm b/Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm
index e78452a..8139d79 100644
--- a/Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm
+++ b/Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm
@@ -16,10 +16,13 @@
#import "Firestore/Source/Auth/FSTEmptyCredentialsProvider.h"
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Util/FSTAssert.h"
#import "Firestore/Source/Util/FSTDispatchQueue.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
+using firebase::firestore::auth::User;
+
NS_ASSUME_NONNULL_BEGIN
@implementation FSTEmptyCredentialsProvider
@@ -33,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
// Since the user never changes, we just need to fire the initial event and don't need to hang
// onto the block.
if (block) {
- block([FSTUser unauthenticatedUser]);
+ block(User::Unauthenticated());
}
}
diff --git a/Firestore/Source/Auth/FSTUser.h b/Firestore/Source/Auth/FSTUser.h
deleted file mode 100644
index 68ecc4c..0000000
--- a/Firestore/Source/Auth/FSTUser.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/**
- * Simple wrapper around a nullable UID. Mostly exists to make code more readable and for use as
- * a key in dictionaries (since keys cannot be nil).
- */
-@interface FSTUser : NSObject <NSCopying>
-
-/** Returns an FSTUser with a nil UID. */
-+ (instancetype)unauthenticatedUser;
-
-// Porting note: no GOOGLE_CREDENTIALS or FIRST_PARTY equivalent on iOS, see FSTGetTokenResult for
-// more details.
-
-/** Initializes an FSTUser with the given UID. */
-- (instancetype)initWithUID:(NSString *_Nullable)UID NS_DESIGNATED_INITIALIZER;
-- (instancetype)init NS_UNAVAILABLE;
-
-@property(nonatomic, copy, nullable, readonly) NSString *UID;
-
-@property(nonatomic, assign, readonly, getter=isUnauthenticated) BOOL unauthenticated;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Auth/FSTUser.mm b/Firestore/Source/Auth/FSTUser.mm
deleted file mode 100644
index 605b4e6..0000000
--- a/Firestore/Source/Auth/FSTUser.mm
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "Firestore/Source/Auth/FSTUser.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-#pragma mark - FSTUser
-
-@implementation FSTUser
-
-@dynamic unauthenticated;
-
-+ (instancetype)unauthenticatedUser {
- return [[FSTUser alloc] initWithUID:nil];
-}
-
-- (instancetype)initWithUID:(NSString *_Nullable)UID {
- if (self = [super init]) {
- _UID = UID;
- }
- return self;
-}
-
-- (BOOL)isEqual:(id)object {
- if (self == object) {
- return YES;
- } else if (![object isKindOfClass:[FSTUser class]]) {
- return NO;
- } else {
- FSTUser *other = object;
- return (self.isUnauthenticated && other.isUnauthenticated) ||
- [self.UID isEqualToString:other.UID];
- }
-}
-
-- (NSUInteger)hash {
- return [self.UID hash];
-}
-
-- (id)copyWithZone:(nullable NSZone *)zone {
- return self; // since FSTUser objects are immutable
-}
-
-- (NSString *)description {
- return [NSString stringWithFormat:@"<FSTUser uid=%@>", self.UID];
-}
-
-- (BOOL)isUnauthenticated {
- return self.UID == nil;
-}
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Core/FSTFirestoreClient.mm b/Firestore/Source/Core/FSTFirestoreClient.mm
index 1961460..823f488 100644
--- a/Firestore/Source/Core/FSTFirestoreClient.mm
+++ b/Firestore/Source/Core/FSTFirestoreClient.mm
@@ -38,6 +38,8 @@
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+namespace util = firebase::firestore::util;
+using firebase::firestore::auth::User;
using firebase::firestore::core::DatabaseInfo;
using firebase::firestore::model::DatabaseId;
@@ -98,13 +100,15 @@ NS_ASSUME_NONNULL_BEGIN
_workerDispatchQueue = workerDispatchQueue;
dispatch_semaphore_t initialUserAvailable = dispatch_semaphore_create(0);
- __block FSTUser *initialUser;
+ __block bool initialized = false;
+ __block User initialUser;
FSTWeakify(self);
- _credentialsProvider.userChangeListener = ^(FSTUser *user) {
+ _credentialsProvider.userChangeListener = ^(const User &user) {
FSTStrongify(self);
if (self) {
- if (!initialUser) {
+ if (!initialized) {
initialUser = user;
+ initialized = true;
dispatch_semaphore_signal(initialUserAvailable);
} else {
[workerDispatchQueue dispatchAsync:^{
@@ -126,7 +130,7 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
-- (void)initializeWithUser:(FSTUser *)user usePersistence:(BOOL)usePersistence {
+- (void)initializeWithUser:(const User &)user usePersistence:(BOOL)usePersistence {
// Do all of our initialization on our own dispatch queue.
[self.workerDispatchQueue verifyIsCurrentQueue];
@@ -189,10 +193,10 @@ NS_ASSUME_NONNULL_BEGIN
[_remoteStore start];
}
-- (void)userDidChange:(FSTUser *)user {
+- (void)userDidChange:(const User &)user {
[self.workerDispatchQueue verifyIsCurrentQueue];
- FSTLog(@"User Changed: %@", user);
+ FSTLog(@"User Changed: %@", util::WrapNSStringNoCopy(user.uid()));
[self.syncEngine userDidChange:user];
}
diff --git a/Firestore/Source/Core/FSTSyncEngine.h b/Firestore/Source/Core/FSTSyncEngine.h
index 7060155..3b28e36 100644
--- a/Firestore/Source/Core/FSTSyncEngine.h
+++ b/Firestore/Source/Core/FSTSyncEngine.h
@@ -19,13 +19,14 @@
#import "Firestore/Source/Core/FSTTypes.h"
#import "Firestore/Source/Remote/FSTRemoteStore.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
@class FSTDispatchQueue;
@class FSTLocalStore;
@class FSTMutation;
@class FSTQuery;
@class FSTRemoteEvent;
@class FSTRemoteStore;
-@class FSTUser;
@class FSTViewSnapshot;
NS_ASSUME_NONNULL_BEGIN
@@ -57,7 +58,8 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithLocalStore:(FSTLocalStore *)localStore
remoteStore:(FSTRemoteStore *)remoteStore
- initialUser:(FSTUser *)user NS_DESIGNATED_INITIALIZER;
+ initialUser:(const firebase::firestore::auth::User &)user
+ NS_DESIGNATED_INITIALIZER;
/**
* A delegate to be notified when queries being listened to produce new view snapshots or
@@ -98,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN
updateBlock:(FSTTransactionBlock)updateBlock
completion:(FSTVoidIDErrorBlock)completion;
-- (void)userDidChange:(FSTUser *)user;
+- (void)userDidChange:(const firebase::firestore::auth::User &)user;
/** Applies an FSTOnlineState change to the sync engine and notifies any views of the change. */
- (void)applyChangedOnlineState:(FSTOnlineState)onlineState;
diff --git a/Firestore/Source/Core/FSTSyncEngine.mm b/Firestore/Source/Core/FSTSyncEngine.mm
index d6ee956..61fac7d 100644
--- a/Firestore/Source/Core/FSTSyncEngine.mm
+++ b/Firestore/Source/Core/FSTSyncEngine.mm
@@ -16,10 +16,11 @@
#import "Firestore/Source/Core/FSTSyncEngine.h"
+#include <unordered_map>
+
#import <GRPCClient/GRPCCall.h>
#import "FIRFirestoreErrors.h"
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Core/FSTQuery.h"
#import "Firestore/Source/Core/FSTSnapshotVersion.h"
#import "Firestore/Source/Core/FSTTransaction.h"
@@ -40,8 +41,11 @@
#import "Firestore/Source/Util/FSTDispatchQueue.h"
#import "Firestore/Source/Util/FSTLogger.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
#include "Firestore/core/src/firebase/firestore/core/target_id_generator.h"
+using firebase::firestore::auth::HashUser;
+using firebase::firestore::auth::User;
using firebase::firestore::core::TargetIdGenerator;
NS_ASSUME_NONNULL_BEGIN
@@ -139,23 +143,22 @@ static const FSTListenSequenceNumber kIrrelevantSequenceNumber = -1;
/** The garbage collector used to collect documents that are no longer in limbo. */
@property(nonatomic, strong, readonly) FSTEagerGarbageCollector *limboCollector;
-/** Stores user completion blocks, indexed by user and FSTBatchID. */
-@property(nonatomic, strong)
- NSMutableDictionary<FSTUser *, NSMutableDictionary<NSNumber *, FSTVoidErrorBlock> *>
- *mutationCompletionBlocks;
-
-@property(nonatomic, strong) FSTUser *currentUser;
-
@end
@implementation FSTSyncEngine {
/** Used for creating the FSTTargetIDs for the listens used to resolve limbo documents. */
TargetIdGenerator _targetIdGenerator;
+
+ /** Stores user completion blocks, indexed by user and FSTBatchID. */
+ std::unordered_map<User, NSMutableDictionary<NSNumber *, FSTVoidErrorBlock> *, HashUser>
+ _mutationCompletionBlocks;
+
+ User _currentUser;
}
- (instancetype)initWithLocalStore:(FSTLocalStore *)localStore
remoteStore:(FSTRemoteStore *)remoteStore
- initialUser:(FSTUser *)initialUser {
+ initialUser:(const User &)initialUser {
if (self = [super init]) {
_localStore = localStore;
_remoteStore = remoteStore;
@@ -169,7 +172,6 @@ static const FSTListenSequenceNumber kIrrelevantSequenceNumber = -1;
_limboDocumentRefs = [[FSTReferenceSet alloc] init];
[_limboCollector addGarbageSource:_limboDocumentRefs];
- _mutationCompletionBlocks = [NSMutableDictionary dictionary];
_targetIdGenerator = TargetIdGenerator::SyncEngineTargetIdGenerator(0);
_currentUser = initialUser;
}
@@ -227,10 +229,10 @@ static const FSTListenSequenceNumber kIrrelevantSequenceNumber = -1;
- (void)addMutationCompletionBlock:(FSTVoidErrorBlock)completion batchID:(FSTBatchID)batchID {
NSMutableDictionary<NSNumber *, FSTVoidErrorBlock> *completionBlocks =
- self.mutationCompletionBlocks[self.currentUser];
+ _mutationCompletionBlocks[_currentUser];
if (!completionBlocks) {
completionBlocks = [NSMutableDictionary dictionary];
- self.mutationCompletionBlocks[self.currentUser] = completionBlocks;
+ _mutationCompletionBlocks[_currentUser] = completionBlocks;
}
[completionBlocks setObject:completion forKey:@(batchID)];
}
@@ -400,7 +402,7 @@ static const FSTListenSequenceNumber kIrrelevantSequenceNumber = -1;
- (void)processUserCallbacksForBatchID:(FSTBatchID)batchID error:(NSError *_Nullable)error {
NSMutableDictionary<NSNumber *, FSTVoidErrorBlock> *completionBlocks =
- self.mutationCompletionBlocks[self.currentUser];
+ _mutationCompletionBlocks[_currentUser];
// NOTE: Mutations restored from persistence won't have completion blocks, so it's okay for
// this (or the completion below) to be nil.
@@ -527,8 +529,8 @@ static const FSTListenSequenceNumber kIrrelevantSequenceNumber = -1;
return [self.limboTargetsByKey copy];
}
-- (void)userDidChange:(FSTUser *)user {
- self.currentUser = user;
+- (void)userDidChange:(const User &)user {
+ _currentUser = user;
// Notify local store and emit any resulting events from swapping out the mutation queue.
FSTMaybeDocumentDictionary *changes = [self.localStore userDidChange:user];
diff --git a/Firestore/Source/Local/FSTLevelDB.mm b/Firestore/Source/Local/FSTLevelDB.mm
index 7fb3a66..9d3c35e 100644
--- a/Firestore/Source/Local/FSTLevelDB.mm
+++ b/Firestore/Source/Local/FSTLevelDB.mm
@@ -29,11 +29,13 @@
#import "Firestore/Source/Util/FSTAssert.h"
#import "Firestore/Source/Util/FSTLogger.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
#include "Firestore/core/src/firebase/firestore/core/database_info.h"
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
namespace util = firebase::firestore::util;
+using firebase::firestore::auth::User;
using firebase::firestore::core::DatabaseInfo;
using firebase::firestore::model::DatabaseId;
@@ -198,7 +200,7 @@ using leveldb::WriteOptions;
#pragma mark - Persistence Factory methods
-- (id<FSTMutationQueue>)mutationQueueForUser:(FSTUser *)user {
+- (id<FSTMutationQueue>)mutationQueueForUser:(const User &)user {
return [FSTLevelDBMutationQueue mutationQueueWithUser:user db:_ptr serializer:self.serializer];
}
diff --git a/Firestore/Source/Local/FSTLevelDBMutationQueue.h b/Firestore/Source/Local/FSTLevelDBMutationQueue.h
index cc05db7..3f1bd51 100644
--- a/Firestore/Source/Local/FSTLevelDBMutationQueue.h
+++ b/Firestore/Source/Local/FSTLevelDBMutationQueue.h
@@ -19,11 +19,12 @@
#include <memory>
#import "Firestore/Source/Local/FSTMutationQueue.h"
+
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
#include "leveldb/db.h"
@class FSTLevelDB;
@class FSTLocalSerializer;
-@class FSTUser;
@protocol FSTGarbageCollector;
NS_ASSUME_NONNULL_BEGIN
@@ -42,7 +43,7 @@ NS_ASSUME_NONNULL_BEGIN
* @param user The user for which to create a mutation queue.
* @param db The LevelDB in which to create the queue.
*/
-+ (instancetype)mutationQueueWithUser:(FSTUser *)user
++ (instancetype)mutationQueueWithUser:(const firebase::firestore::auth::User &)user
db:(std::shared_ptr<leveldb::DB>)db
serializer:(FSTLocalSerializer *)serializer;
diff --git a/Firestore/Source/Local/FSTLevelDBMutationQueue.mm b/Firestore/Source/Local/FSTLevelDBMutationQueue.mm
index 85f163d..982e09c 100644
--- a/Firestore/Source/Local/FSTLevelDBMutationQueue.mm
+++ b/Firestore/Source/Local/FSTLevelDBMutationQueue.mm
@@ -22,7 +22,6 @@
#include <string>
#import "Firestore/Protos/objc/firestore/local/Mutation.pbobjc.h"
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Core/FSTQuery.h"
#import "Firestore/Source/Local/FSTLevelDB.h"
#import "Firestore/Source/Local/FSTLevelDBKey.h"
@@ -34,12 +33,15 @@
#import "Firestore/Source/Model/FSTPath.h"
#import "Firestore/Source/Util/FSTAssert.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
#include "Firestore/core/src/firebase/firestore/util/string_util.h"
NS_ASSUME_NONNULL_BEGIN
namespace util = firebase::firestore::util;
using Firestore::StringView;
+using firebase::firestore::auth::User;
using leveldb::DB;
using leveldb::Iterator;
using leveldb::ReadOptions;
@@ -89,11 +91,10 @@ static ReadOptions StandardReadOptions() {
std::shared_ptr<DB> _db;
}
-+ (instancetype)mutationQueueWithUser:(FSTUser *)user
++ (instancetype)mutationQueueWithUser:(const User &)user
db:(std::shared_ptr<DB>)db
serializer:(FSTLocalSerializer *)serializer {
- FSTAssert(![user.UID isEqual:@""], @"UserID must not be an empty string.");
- NSString *userID = user.isUnauthenticated ? @"" : user.UID;
+ NSString *userID = user.is_authenticated() ? util::WrapNSStringNoCopy(user.uid()) : @"";
return [[FSTLevelDBMutationQueue alloc] initWithUserID:userID db:db serializer:serializer];
}
diff --git a/Firestore/Source/Local/FSTLocalStore.h b/Firestore/Source/Local/FSTLocalStore.h
index 19803ac..4ec23fd 100644
--- a/Firestore/Source/Local/FSTLocalStore.h
+++ b/Firestore/Source/Local/FSTLocalStore.h
@@ -21,6 +21,8 @@
#import "Firestore/Source/Model/FSTDocumentKeySet.h"
#import "Firestore/Source/Model/FSTDocumentVersionDictionary.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
@class FSTLocalViewChanges;
@class FSTLocalWriteResult;
@class FSTMutation;
@@ -29,7 +31,6 @@
@class FSTQuery;
@class FSTQueryData;
@class FSTRemoteEvent;
-@class FSTUser;
@protocol FSTPersistence;
@protocol FSTGarbageCollector;
@@ -80,7 +81,8 @@ NS_ASSUME_NONNULL_BEGIN
/** Creates a new instance of the FSTLocalStore with its required dependencies as parameters. */
- (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
garbageCollector:(id<FSTGarbageCollector>)garbageCollector
- initialUser:(FSTUser *)initialUser NS_DESIGNATED_INITIALIZER;
+ initialUser:(const firebase::firestore::auth::User &)initialUser
+ NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@@ -96,7 +98,7 @@ NS_ASSUME_NONNULL_BEGIN
* In response the local store switches the mutation queue to the new user and returns any
* resulting document changes.
*/
-- (FSTMaybeDocumentDictionary *)userDidChange:(FSTUser *)user;
+- (FSTMaybeDocumentDictionary *)userDidChange:(const firebase::firestore::auth::User &)user;
/** Accepts locally generated Mutations and commits them to storage. */
- (FSTLocalWriteResult *)locallyWriteMutations:(NSArray<FSTMutation *> *)mutations;
diff --git a/Firestore/Source/Local/FSTLocalStore.mm b/Firestore/Source/Local/FSTLocalStore.mm
index 8a383e5..d12a45b 100644
--- a/Firestore/Source/Local/FSTLocalStore.mm
+++ b/Firestore/Source/Local/FSTLocalStore.mm
@@ -16,7 +16,6 @@
#import "Firestore/Source/Local/FSTLocalStore.h"
-#import "Firestore/Source/Auth/FSTUser.h"
#import "Firestore/Source/Core/FSTListenSequence.h"
#import "Firestore/Source/Core/FSTQuery.h"
#import "Firestore/Source/Core/FSTSnapshotVersion.h"
@@ -41,8 +40,10 @@
#import "Firestore/Source/Util/FSTAssert.h"
#import "Firestore/Source/Util/FSTLogger.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
#include "Firestore/core/src/firebase/firestore/core/target_id_generator.h"
+using firebase::firestore::auth::User;
using firebase::firestore::core::TargetIdGenerator;
NS_ASSUME_NONNULL_BEGIN
@@ -99,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
garbageCollector:(id<FSTGarbageCollector>)garbageCollector
- initialUser:(FSTUser *)initialUser {
+ initialUser:(const User &)initialUser {
if (self = [super init]) {
_persistence = persistence;
_mutationQueue = [persistence mutationQueueForUser:initialUser];
@@ -166,7 +167,7 @@ NS_ASSUME_NONNULL_BEGIN
[self.queryCache shutdown];
}
-- (FSTMaybeDocumentDictionary *)userDidChange:(FSTUser *)user {
+- (FSTMaybeDocumentDictionary *)userDidChange:(const User &)user {
// Swap out the mutation queue, grabbing the pending mutation batches before and after.
NSArray<FSTMutationBatch *> *oldBatches = [self.mutationQueue allMutationBatches];
diff --git a/Firestore/Source/Local/FSTMemoryPersistence.mm b/Firestore/Source/Local/FSTMemoryPersistence.mm
index e301820..ba71f9c 100644
--- a/Firestore/Source/Local/FSTMemoryPersistence.mm
+++ b/Firestore/Source/Local/FSTMemoryPersistence.mm
@@ -16,7 +16,8 @@
#import "Firestore/Source/Local/FSTMemoryPersistence.h"
-#import "Firestore/Source/Auth/FSTUser.h"
+#include <unordered_map>
+
#import "Firestore/Source/Local/FSTMemoryMutationQueue.h"
#import "Firestore/Source/Local/FSTMemoryQueryCache.h"
#import "Firestore/Source/Local/FSTMemoryRemoteDocumentCache.h"
@@ -24,12 +25,15 @@
#import "Firestore/Source/Local/FSTWriteGroupTracker.h"
#import "Firestore/Source/Util/FSTAssert.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
+using firebase::firestore::auth::HashUser;
+using firebase::firestore::auth::User;
+
NS_ASSUME_NONNULL_BEGIN
@interface FSTMemoryPersistence ()
@property(nonatomic, strong, nonnull) FSTWriteGroupTracker *writeGroupTracker;
-@property(nonatomic, strong, nonnull)
- NSMutableDictionary<FSTUser *, id<FSTMutationQueue>> *mutationQueues;
@property(nonatomic, assign, getter=isStarted) BOOL started;
@end
@@ -46,6 +50,8 @@ NS_ASSUME_NONNULL_BEGIN
/** The FSTRemoteDocumentCache representing the persisted cache of remote documents. */
FSTMemoryRemoteDocumentCache *_remoteDocumentCache;
+
+ std::unordered_map<User, id<FSTMutationQueue>, HashUser> _mutationQueues;
}
+ (instancetype)persistence {
@@ -57,7 +63,6 @@ NS_ASSUME_NONNULL_BEGIN
_writeGroupTracker = [FSTWriteGroupTracker tracker];
_queryCache = [[FSTMemoryQueryCache alloc] init];
_remoteDocumentCache = [[FSTMemoryRemoteDocumentCache alloc] init];
- _mutationQueues = [NSMutableDictionary dictionary];
}
return self;
}
@@ -75,11 +80,11 @@ NS_ASSUME_NONNULL_BEGIN
self.started = NO;
}
-- (id<FSTMutationQueue>)mutationQueueForUser:(FSTUser *)user {
- id<FSTMutationQueue> queue = self.mutationQueues[user];
+- (id<FSTMutationQueue>)mutationQueueForUser:(const User &)user {
+ id<FSTMutationQueue> queue = _mutationQueues[user];
if (!queue) {
queue = [FSTMemoryMutationQueue mutationQueue];
- self.mutationQueues[user] = queue;
+ _mutationQueues[user] = queue;
}
return queue;
}
diff --git a/Firestore/Source/Local/FSTPersistence.h b/Firestore/Source/Local/FSTPersistence.h
index cf07a9e..30eb211 100644
--- a/Firestore/Source/Local/FSTPersistence.h
+++ b/Firestore/Source/Local/FSTPersistence.h
@@ -16,7 +16,8 @@
#import <Foundation/Foundation.h>
-@class FSTUser;
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
@class FSTWriteGroup;
@protocol FSTMutationQueue;
@protocol FSTQueryCache;
@@ -75,7 +76,7 @@ NS_ASSUME_NONNULL_BEGIN
* implementation to the extent possible (e.g. in the case of uid switching from
* sally=>jack=>sally, sally's mutation queue will be preserved).
*/
-- (id<FSTMutationQueue>)mutationQueueForUser:(FSTUser *)user;
+- (id<FSTMutationQueue>)mutationQueueForUser:(const firebase::firestore::auth::User &)user;
/** Creates an FSTQueryCache representing the persisted cache of queries. */
- (id<FSTQueryCache>)queryCache;
diff --git a/Firestore/Source/Remote/FSTRemoteStore.h b/Firestore/Source/Remote/FSTRemoteStore.h
index b5dd204..4ea9379 100644
--- a/Firestore/Source/Remote/FSTRemoteStore.h
+++ b/Firestore/Source/Remote/FSTRemoteStore.h
@@ -19,6 +19,8 @@
#import "Firestore/Source/Core/FSTTypes.h"
#import "Firestore/Source/Model/FSTDocumentVersionDictionary.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+
@class FSTDatastore;
@class FSTDocumentKey;
@class FSTLocalStore;
@@ -28,7 +30,6 @@
@class FSTQueryData;
@class FSTRemoteEvent;
@class FSTTransaction;
-@class FSTUser;
NS_ASSUME_NONNULL_BEGIN
@@ -121,7 +122,7 @@ NS_ASSUME_NONNULL_BEGIN
* In response the remote store tears down streams and clears up any tracked operations that should
* not persist across users. Restarts the streams if appropriate.
*/
-- (void)userDidChange:(FSTUser *)user;
+- (void)userDidChange:(const firebase::firestore::auth::User &)user;
/** Listens to the target identified by the given FSTQueryData. */
- (void)listenToTargetWithQueryData:(FSTQueryData *)queryData;
diff --git a/Firestore/Source/Remote/FSTRemoteStore.mm b/Firestore/Source/Remote/FSTRemoteStore.mm
index 123df49..c6668bf 100644
--- a/Firestore/Source/Remote/FSTRemoteStore.mm
+++ b/Firestore/Source/Remote/FSTRemoteStore.mm
@@ -35,6 +35,12 @@
#import "Firestore/Source/Util/FSTAssert.h"
#import "Firestore/Source/Util/FSTLogger.h"
+#include "Firestore/core/src/firebase/firestore/auth/user.h"
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+
+namespace util = firebase::firestore::util;
+using firebase::firestore::auth::User;
+
NS_ASSUME_NONNULL_BEGIN
/**
@@ -268,8 +274,9 @@ static const int kOnlineAttemptsBeforeFailure = 2;
[self updateOnlineState:FSTOnlineStateUnknown];
}
-- (void)userDidChange:(FSTUser *)user {
- FSTLog(@"FSTRemoteStore %p changing users: %@", (__bridge void *)self, user);
+- (void)userDidChange:(const User &)user {
+ FSTLog(@"FSTRemoteStore %p changing users: %@", (__bridge void *)self,
+ util::WrapNSStringNoCopy(user.uid()));
if ([self isNetworkEnabled]) {
// Tear down and re-create our network streams. This will ensure we get a fresh auth token
// for the new user and re-fill the write pipeline with new mutations from the LocalStore
diff --git a/Firestore/core/src/firebase/firestore/auth/user.h b/Firestore/core/src/firebase/firestore/auth/user.h
index 58b8b55..cc7b66d 100644
--- a/Firestore/core/src/firebase/firestore/auth/user.h
+++ b/Firestore/core/src/firebase/firestore/auth/user.h
@@ -17,6 +17,11 @@
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_USER_H_
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_USER_H_
+#if defined(__OBJC__)
+#import <Foundation/Foundation.h>
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+#endif // defined(__OBJC__)
+
#include <string>
#include "absl/strings/string_view.h"
@@ -38,6 +43,12 @@ class User {
/** Construct an authenticated user with the given UID. */
explicit User(const absl::string_view uid);
+#if defined(__OBJC__)
+ explicit User(NSString* uid)
+ : User(firebase::firestore::util::MakeStringView(uid)) {
+ }
+#endif // defined(__OBJC__)
+
const std::string& uid() const {
return uid_;
}
@@ -69,6 +80,14 @@ inline bool operator!=(const User& lhs, const User& rhs) {
return !(lhs == rhs);
}
+// Specializations of std::hash is prohibited. We define a hash function to be
+// passed through manually.
+struct HashUser {
+ inline int64_t operator()(const User& user) const {
+ return std::hash<std::string>{}(user.uid());
+ }
+};
+
} // namespace auth
} // namespace firestore
} // namespace firebase
diff --git a/Firestore/core/test/firebase/firestore/auth/user_test.cc b/Firestore/core/test/firebase/firestore/auth/user_test.cc
index a9f764d..7277283 100644
--- a/Firestore/core/test/firebase/firestore/auth/user_test.cc
+++ b/Firestore/core/test/firebase/firestore/auth/user_test.cc
@@ -49,6 +49,11 @@ TEST(User, Comparison) {
EXPECT_NE(User("abc"), User("xyz"));
}
+TEST(User, Hash) {
+ const HashUser hash;
+ EXPECT_EQ(hash(User("abc")), hash(User("abc")));
+}
+
} // namespace auth
} // namespace firestore
} // namespace firebase