From 3e7c062f3baca83fae1937bf60865be0cd18f96d Mon Sep 17 00:00:00 2001 From: zxu Date: Tue, 27 Feb 2018 14:04:39 -0500 Subject: replacing Auth by C++ auth implementation (#802) * lazy replacing FST(Firebase)CredentialsProvider by (Firebase)CredentialsProvider * lazy replacing FSTUser by User * adding error-code parameter to TokenListener * actually use const user& instead of pointer; also add an error util * add HashUser and pass into the unordered_map * use User in test * use c++ CredentialsProvider and subclass in test * fix unit test * use explicit capture in lambda instead of capture all by reference * cache currentUser explicitly when reset sync engineer test driver * objc object should be captured by value in lambda * replacing Auth/FSTUser by C++ auth implementation * address changes * replacing FSTGetTokenResult by C++ Token implementation * address changes * fix unintentional change in merging * patch the change in objc Auth up-stream * somehow, the lambda-version of set-user-change-listener does not work... fallback to block * address changes * fix another const& v.s. dispatch bug * fix more const& v.s. dispatch bug zxu123 committed * fix a bad sync line * address changes * address change * address change * fix upstream change from merge * fix upstream changes * Suggested fixes for cpp/port_auth (#846) * Get rid of MockDatastore factory This avoids the need to statically allocate (and leak) a credentials provider * Use absl::make_unique std::make_unique technically does not exist until C++14. * #include for std::move * Use std::future for the initial user * fix style --- Firestore/Source/Core/FSTFirestoreClient.h | 5 ++- Firestore/Source/Core/FSTFirestoreClient.mm | 59 ++++++++++++++++------------- 2 files changed, 36 insertions(+), 28 deletions(-) (limited to 'Firestore/Source/Core') diff --git a/Firestore/Source/Core/FSTFirestoreClient.h b/Firestore/Source/Core/FSTFirestoreClient.h index 56101ab..6da5ed3 100644 --- a/Firestore/Source/Core/FSTFirestoreClient.h +++ b/Firestore/Source/Core/FSTFirestoreClient.h @@ -20,6 +20,7 @@ #import "Firestore/Source/Core/FSTViewSnapshot.h" #import "Firestore/Source/Remote/FSTRemoteStore.h" +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" #include "Firestore/core/src/firebase/firestore/core/database_info.h" #include "Firestore/core/src/firebase/firestore/model/database_id.h" @@ -30,7 +31,6 @@ @class FSTQuery; @class FSTQueryListener; @class FSTTransaction; -@protocol FSTCredentialsProvider; NS_ASSUME_NONNULL_BEGIN @@ -48,7 +48,8 @@ NS_ASSUME_NONNULL_BEGIN */ + (instancetype)clientWithDatabaseInfo:(const firebase::firestore::core::DatabaseInfo &)databaseInfo usePersistence:(BOOL)usePersistence - credentialsProvider:(id)credentialsProvider + credentialsProvider:(firebase::firestore::auth::CredentialsProvider *) + credentialsProvider // no passing ownership userDispatchQueue:(FSTDispatchQueue *)userDispatchQueue workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue; diff --git a/Firestore/Source/Core/FSTFirestoreClient.mm b/Firestore/Source/Core/FSTFirestoreClient.mm index c60bb7c..fb86e0b 100644 --- a/Firestore/Source/Core/FSTFirestoreClient.mm +++ b/Firestore/Source/Core/FSTFirestoreClient.mm @@ -16,7 +16,8 @@ #import "Firestore/Source/Core/FSTFirestoreClient.h" -#import "Firestore/Source/Auth/FSTCredentialsProvider.h" +#import + #import "Firestore/Source/Core/FSTEventManager.h" #import "Firestore/Source/Core/FSTSyncEngine.h" #import "Firestore/Source/Core/FSTTransaction.h" @@ -34,11 +35,13 @@ #import "Firestore/Source/Util/FSTDispatchQueue.h" #import "Firestore/Source/Util/FSTLogger.h" +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.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::CredentialsProvider; using firebase::firestore::auth::User; using firebase::firestore::core::DatabaseInfo; using firebase::firestore::model::DatabaseId; @@ -51,7 +54,8 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithDatabaseInfo:(const DatabaseInfo &)databaseInfo usePersistence:(BOOL)usePersistence - credentialsProvider:(id)credentialsProvider + credentialsProvider: + (CredentialsProvider *)credentialsProvider // no passing ownership userDispatchQueue:(FSTDispatchQueue *)userDispatchQueue workerDispatchQueue:(FSTDispatchQueue *)queue NS_DESIGNATED_INITIALIZER; @@ -70,7 +74,8 @@ NS_ASSUME_NONNULL_BEGIN */ @property(nonatomic, strong, readonly) FSTDispatchQueue *workerDispatchQueue; -@property(nonatomic, strong, readonly) id credentialsProvider; +// Does not own the CredentialsProvider instance. +@property(nonatomic, assign, readonly) CredentialsProvider *credentialsProvider; @end @@ -78,7 +83,8 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)clientWithDatabaseInfo:(const DatabaseInfo &)databaseInfo usePersistence:(BOOL)usePersistence - credentialsProvider:(id)credentialsProvider + credentialsProvider: + (CredentialsProvider *)credentialsProvider // no passing ownership userDispatchQueue:(FSTDispatchQueue *)userDispatchQueue workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue { return [[FSTFirestoreClient alloc] initWithDatabaseInfo:databaseInfo @@ -90,7 +96,8 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithDatabaseInfo:(const DatabaseInfo &)databaseInfo usePersistence:(BOOL)usePersistence - credentialsProvider:(id)credentialsProvider + credentialsProvider: + (CredentialsProvider *)credentialsProvider // no passing ownership userDispatchQueue:(FSTDispatchQueue *)userDispatchQueue workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue { if (self = [super init]) { @@ -99,32 +106,32 @@ NS_ASSUME_NONNULL_BEGIN _userDispatchQueue = userDispatchQueue; _workerDispatchQueue = workerDispatchQueue; - dispatch_semaphore_t initialUserAvailable = dispatch_semaphore_create(0); - __block bool initialized = false; - __block User initialUser; - FSTWeakify(self); - _credentialsProvider.userChangeListener = ^(User user) { - FSTStrongify(self); - if (self) { - if (!initialized) { - initialUser = user; - initialized = true; - dispatch_semaphore_signal(initialUserAvailable); - } else { - [workerDispatchQueue dispatchAsync:^{ - [self userDidChange:user]; - }]; - } + auto userPromise = std::make_shared>(); + + __weak typeof(self) weakSelf = self; + auto userChangeListener = [initialized = false, userPromise, weakSelf, + workerDispatchQueue](User user) mutable { + typeof(self) strongSelf = weakSelf; + if (!strongSelf) return; + + if (!initialized) { + initialized = true; + userPromise->set_value(user); + } else { + [workerDispatchQueue dispatchAsync:^{ + [strongSelf userDidChange:user]; + }]; } }; + _credentialsProvider->SetUserChangeListener(userChangeListener); + // Defer initialization until we get the current user from the userChangeListener. This is // guaranteed to be synchronously dispatched onto our worker queue, so we will be initialized // before any subsequently queued work runs. [_workerDispatchQueue dispatchAsync:^{ - dispatch_semaphore_wait(initialUserAvailable, DISPATCH_TIME_FOREVER); - - [self initializeWithUser:initialUser usePersistence:usePersistence]; + User user = userPromise->get_future().get(); + [self initializeWithUser:user usePersistence:usePersistence]; }]; } return self; @@ -172,7 +179,7 @@ NS_ASSUME_NONNULL_BEGIN FSTDatastore *datastore = [FSTDatastore datastoreWithDatabase:self.databaseInfo workerDispatchQueue:self.workerDispatchQueue - credentials:self.credentialsProvider]; + credentials:_credentialsProvider]; _remoteStore = [FSTRemoteStore remoteStoreWithLocalStore:_localStore datastore:datastore]; @@ -229,7 +236,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)shutdownWithCompletion:(nullable FSTVoidErrorBlock)completion { [self.workerDispatchQueue dispatchAsync:^{ - self.credentialsProvider.userChangeListener = nil; + self->_credentialsProvider->SetUserChangeListener(nullptr); [self.remoteStore shutdown]; [self.localStore shutdown]; -- cgit v1.2.3