aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Firestore/Source')
-rw-r--r--Firestore/Source/API/FIRFirestore+Internal.h7
-rw-r--r--Firestore/Source/API/FIRFirestore.mm24
-rw-r--r--Firestore/Source/Auth/FSTCredentialsProvider.h88
-rw-r--r--Firestore/Source/Auth/FSTCredentialsProvider.mm157
-rw-r--r--Firestore/Source/Auth/FSTEmptyCredentialsProvider.h28
-rw-r--r--Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm53
-rw-r--r--Firestore/Source/Core/FSTFirestoreClient.h5
-rw-r--r--Firestore/Source/Core/FSTFirestoreClient.mm59
-rw-r--r--Firestore/Source/Remote/FSTDatastore.h9
-rw-r--r--Firestore/Source/Remote/FSTDatastore.mm51
-rw-r--r--Firestore/Source/Remote/FSTStream.h18
-rw-r--r--Firestore/Source/Remote/FSTStream.mm30
12 files changed, 117 insertions, 412 deletions
diff --git a/Firestore/Source/API/FIRFirestore+Internal.h b/Firestore/Source/API/FIRFirestore+Internal.h
index 7bc419a..a52533d 100644
--- a/Firestore/Source/API/FIRFirestore+Internal.h
+++ b/Firestore/Source/API/FIRFirestore+Internal.h
@@ -16,6 +16,9 @@
#import "FIRFirestore.h"
+#include <memory>
+
+#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h"
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
#include "absl/strings/string_view.h"
@@ -24,7 +27,6 @@ NS_ASSUME_NONNULL_BEGIN
@class FSTDispatchQueue;
@class FSTFirestoreClient;
@class FSTUserDataConverter;
-@protocol FSTCredentialsProvider;
@interface FIRFirestore (/* Init */)
@@ -35,7 +37,8 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithProjectID:(const absl::string_view)projectID
database:(const absl::string_view)database
persistenceKey:(NSString *)persistenceKey
- credentialsProvider:(id<FSTCredentialsProvider>)credentialsProvider
+ credentialsProvider:(std::unique_ptr<firebase::firestore::auth::CredentialsProvider>)
+ credentialsProvider
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
firebaseApp:(FIRApp *)app;
diff --git a/Firestore/Source/API/FIRFirestore.mm b/Firestore/Source/API/FIRFirestore.mm
index ce8f8ab..eff0605 100644
--- a/Firestore/Source/API/FIRFirestore.mm
+++ b/Firestore/Source/API/FIRFirestore.mm
@@ -16,6 +16,10 @@
#import "FIRFirestore.h"
+#include <memory>
+#include <utility>
+
+#import <FirebaseCore/FIRApp.h>
#import <FirebaseCore/FIRAppInternal.h>
#import <FirebaseCore/FIRLogger.h>
#import <FirebaseCore/FIROptions.h>
@@ -28,7 +32,6 @@
#import "Firestore/Source/API/FIRWriteBatch+Internal.h"
#import "Firestore/Source/API/FSTUserDataConverter.h"
-#import "Firestore/Source/Auth/FSTCredentialsProvider.h"
#import "Firestore/Source/Core/FSTFirestoreClient.h"
#import "Firestore/Source/Model/FSTDocumentKey.h"
#import "Firestore/Source/Model/FSTPath.h"
@@ -37,11 +40,16 @@
#import "Firestore/Source/Util/FSTLogger.h"
#import "Firestore/Source/Util/FSTUsageValidation.h"
+#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h"
+#include "Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.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"
+#include "absl/memory/memory.h"
namespace util = firebase::firestore::util;
+using firebase::firestore::auth::CredentialsProvider;
+using firebase::firestore::auth::FirebaseCredentialsProvider;
using firebase::firestore::core::DatabaseInfo;
using firebase::firestore::model::DatabaseId;
@@ -52,10 +60,10 @@ extern "C" NSString *const FIRFirestoreErrorDomain = @"FIRFirestoreErrorDomain";
@interface FIRFirestore () {
/** The actual owned DatabaseId instance is allocated in FIRFirestore. */
DatabaseId _databaseID;
+ std::unique_ptr<CredentialsProvider> _credentialsProvider;
}
@property(nonatomic, strong) NSString *persistenceKey;
-@property(nonatomic, strong) id<FSTCredentialsProvider> credentialsProvider;
@property(nonatomic, strong) FSTDispatchQueue *workerDispatchQueue;
// Note that `client` is updated after initialization, but marking this readwrite would generate an
@@ -152,15 +160,15 @@ extern "C" NSString *const FIRFirestoreErrorDomain = @"FIRFirestoreErrorDomain";
FSTDispatchQueue *workerDispatchQueue = [FSTDispatchQueue
queueWith:dispatch_queue_create("com.google.firebase.firestore", DISPATCH_QUEUE_SERIAL)];
- id<FSTCredentialsProvider> credentialsProvider;
- credentialsProvider = [[FSTFirebaseCredentialsProvider alloc] initWithApp:app];
+ std::unique_ptr<CredentialsProvider> credentials_provider =
+ absl::make_unique<FirebaseCredentialsProvider>(app);
NSString *persistenceKey = app.name;
firestore = [[FIRFirestore alloc] initWithProjectID:util::MakeStringView(projectID)
database:util::MakeStringView(database)
persistenceKey:persistenceKey
- credentialsProvider:credentialsProvider
+ credentialsProvider:std::move(credentials_provider)
workerDispatchQueue:workerDispatchQueue
firebaseApp:app];
instances[key] = firestore;
@@ -173,7 +181,7 @@ extern "C" NSString *const FIRFirestoreErrorDomain = @"FIRFirestoreErrorDomain";
- (instancetype)initWithProjectID:(const absl::string_view)projectID
database:(const absl::string_view)database
persistenceKey:(NSString *)persistenceKey
- credentialsProvider:(id<FSTCredentialsProvider>)credentialsProvider
+ credentialsProvider:(std::unique_ptr<CredentialsProvider>)credentialsProvider
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
firebaseApp:(FIRApp *)app {
if (self = [super init]) {
@@ -190,7 +198,7 @@ extern "C" NSString *const FIRFirestoreErrorDomain = @"FIRFirestoreErrorDomain";
_dataConverter =
[[FSTUserDataConverter alloc] initWithDatabaseID:&_databaseID preConverter:block];
_persistenceKey = persistenceKey;
- _credentialsProvider = credentialsProvider;
+ _credentialsProvider = std::move(credentialsProvider);
_workerDispatchQueue = workerDispatchQueue;
_app = app;
_settings = [[FIRFirestoreSettings alloc] init];
@@ -241,7 +249,7 @@ extern "C" NSString *const FIRFirestoreErrorDomain = @"FIRFirestoreErrorDomain";
_client = [FSTFirestoreClient clientWithDatabaseInfo:database_info
usePersistence:_settings.persistenceEnabled
- credentialsProvider:_credentialsProvider
+ credentialsProvider:_credentialsProvider.get()
userDispatchQueue:userDispatchQueue
workerDispatchQueue:_workerDispatchQueue];
}
diff --git a/Firestore/Source/Auth/FSTCredentialsProvider.h b/Firestore/Source/Auth/FSTCredentialsProvider.h
deleted file mode 100644
index d2f04e0..0000000
--- a/Firestore/Source/Auth/FSTCredentialsProvider.h
+++ /dev/null
@@ -1,88 +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>
-
-#include "Firestore/core/src/firebase/firestore/auth/token.h"
-#include "Firestore/core/src/firebase/firestore/auth/user.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@class FIRApp;
-@class FSTDispatchQueue;
-
-#pragma mark - Typedefs
-
-/**
- * `FSTVoidTokenErrorBlock` is a block that gets a token or an error.
- *
- * @param token An auth token, either valid or invalid when error occurred.
- * @param error The error if one occurred, or else `nil`.
- */
-typedef void (^FSTVoidGetTokenResultBlock)(firebase::firestore::auth::Token token,
- NSError *_Nullable error);
-
-/** Listener block notified with a User. */
-typedef void (^FSTVoidUserBlock)(firebase::firestore::auth::User user);
-
-#pragma mark - FSTCredentialsProvider
-
-/** Provides methods for getting the uid and token for the current user and listen for changes. */
-@protocol FSTCredentialsProvider <NSObject>
-
-/** Requests token for the current user, optionally forcing a refreshed token to be fetched. */
-- (void)getTokenForcingRefresh:(BOOL)forceRefresh completion:(FSTVoidGetTokenResultBlock)completion;
-
-/**
- * A listener to be notified of user changes (sign-in / sign-out). It is immediately called once
- * with the initial user.
- *
- * Note that this block will be called back on an arbitrary thread that is not the normal Firestore
- * worker thread.
- */
-@property(nonatomic, copy, nullable, readwrite) FSTVoidUserBlock userChangeListener;
-
-@end
-
-#pragma mark - FSTFirebaseCredentialsProvider
-
-/**
- * `FSTFirebaseCredentialsProvider` uses Firebase Auth via `FIRApp` to get an auth token.
- *
- * NOTE: To simplify the implementation, it requires that you set `userChangeListener` with a
- * non-`nil` value no more than once and don't call `getTokenForcingRefresh:` after setting
- * it to `nil`.
- *
- * This class must be implemented in a thread-safe manner since it is accessed from the thread
- * backing our internal worker queue and the callbacks from FIRAuth will be executed on an
- * arbitrary different thread.
- */
-@interface FSTFirebaseCredentialsProvider : NSObject <FSTCredentialsProvider>
-
-/**
- * Initializes a new FSTFirebaseCredentialsProvider.
- *
- * @param app The Firebase app from which to get credentials.
- *
- * @return A new instance of FSTFirebaseCredentialsProvider.
- */
-- (instancetype)initWithApp:(FIRApp *)app NS_DESIGNATED_INITIALIZER;
-
-- (id)init NS_UNAVAILABLE;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Auth/FSTCredentialsProvider.mm b/Firestore/Source/Auth/FSTCredentialsProvider.mm
deleted file mode 100644
index e0dc8aa..0000000
--- a/Firestore/Source/Auth/FSTCredentialsProvider.mm
+++ /dev/null
@@ -1,157 +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/FSTCredentialsProvider.h"
-
-#import <FirebaseCore/FIRApp.h>
-#import <FirebaseCore/FIRAppInternal.h>
-#import <GRPCClient/GRPCCall.h>
-
-#import "FIRFirestoreErrors.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/token.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::Token;
-using firebase::firestore::auth::User;
-
-NS_ASSUME_NONNULL_BEGIN
-
-#pragma mark - 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;
-
-/**
- * Counter used to detect if the user changed while a -getTokenForcingRefresh: request was
- * outstanding.
- */
-@property(nonatomic, assign, readwrite) int userCounter;
-
-@end
-
-@implementation FSTFirebaseCredentialsProvider {
- FSTVoidUserBlock _userChangeListener;
-}
-
-- (instancetype)initWithApp:(FIRApp *)app {
- self = [super init];
- if (self) {
- _app = app;
- _currentUser = User::FromUid([self.app getUID]);
- _userCounter = 0;
-
- // Register for user changes so that we can internally track the current user.
- FSTWeakify(self);
- _authListenerHandle = [[NSNotificationCenter defaultCenter]
- addObserverForName:FIRAuthStateDidChangeInternalNotification
- object:nil
- queue:nil
- usingBlock:^(NSNotification *notification) {
- FSTStrongify(self);
- if (self) {
- @synchronized(self) {
- NSDictionary *userInfo = notification.userInfo;
-
- // ensure we're only notifiying for the current app.
- FIRApp *notifiedApp =
- userInfo[FIRAuthStateDidChangeInternalNotificationAppKey];
- if (![self.app isEqual:notifiedApp]) {
- return;
- }
-
- NSString *uid = userInfo[FIRAuthStateDidChangeInternalNotificationUIDKey];
- User newUser = User::FromUid(uid);
- if (newUser != self->_currentUser) {
- self->_currentUser = newUser;
- self.userCounter++;
- FSTVoidUserBlock listenerBlock = self.userChangeListener;
- if (listenerBlock) {
- listenerBlock(self->_currentUser);
- }
- }
- }
- }
- }];
- }
- return self;
-}
-
-- (void)getTokenForcingRefresh:(BOOL)forceRefresh
- completion:(FSTVoidGetTokenResultBlock)completion {
- FSTAssert(self.authListenerHandle, @"getToken cannot be called after listener removed.");
-
- // Take note of the current value of the userCounter so that this method can fail (with a
- // FIRFirestoreErrorCodeAborted error) if there is a user change while the request is outstanding.
- int initialUserCounter = self.userCounter;
-
- void (^getTokenCallback)(NSString *, NSError *) =
- ^(NSString *_Nullable token, NSError *_Nullable error) {
- @synchronized(self) {
- if (initialUserCounter != self.userCounter) {
- // Cancel the request since the user changed while the request was outstanding so the
- // response is likely for a previous user (which user, we can't be sure).
- NSDictionary *errorInfo = @{@"details" : @"getToken aborted due to user change."};
- NSError *cancelError = [NSError errorWithDomain:FIRFirestoreErrorDomain
- code:FIRFirestoreErrorCodeAborted
- userInfo:errorInfo];
- completion(Token::Invalid(), cancelError);
- } else {
- completion(Token(util::MakeStringView(token), self->_currentUser), error);
- }
- };
- };
-
- [self.app getTokenForcingRefresh:forceRefresh withCallback:getTokenCallback];
-}
-
-- (void)setUserChangeListener:(nullable FSTVoidUserBlock)block {
- @synchronized(self) {
- if (block) {
- FSTAssert(!_userChangeListener, @"UserChangeListener set twice!");
-
- // Fire initial event.
- block(_currentUser);
- } else {
- FSTAssert(self.authListenerHandle, @"UserChangeListener removed twice!");
- FSTAssert(_userChangeListener, @"UserChangeListener removed without being set!");
- [[NSNotificationCenter defaultCenter] removeObserver:self.authListenerHandle];
- self.authListenerHandle = nil;
- }
- _userChangeListener = block;
- }
-}
-
-- (nullable FSTVoidUserBlock)userChangeListener {
- @synchronized(self) {
- return _userChangeListener;
- }
-}
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Auth/FSTEmptyCredentialsProvider.h b/Firestore/Source/Auth/FSTEmptyCredentialsProvider.h
deleted file mode 100644
index f805363..0000000
--- a/Firestore/Source/Auth/FSTEmptyCredentialsProvider.h
+++ /dev/null
@@ -1,28 +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>
-
-#import "Firestore/Source/Auth/FSTCredentialsProvider.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** `FSTEmptyCredentialsProvider` always yields an empty token. */
-@interface FSTEmptyCredentialsProvider : NSObject <FSTCredentialsProvider>
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm b/Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm
deleted file mode 100644
index 77c08d1..0000000
--- a/Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm
+++ /dev/null
@@ -1,53 +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/FSTEmptyCredentialsProvider.h"
-
-#import "Firestore/Source/Util/FSTAssert.h"
-#import "Firestore/Source/Util/FSTDispatchQueue.h"
-
-#include "Firestore/core/src/firebase/firestore/auth/token.h"
-#include "Firestore/core/src/firebase/firestore/auth/user.h"
-
-using firebase::firestore::auth::Token;
-using firebase::firestore::auth::User;
-
-NS_ASSUME_NONNULL_BEGIN
-
-@implementation FSTEmptyCredentialsProvider
-
-- (void)getTokenForcingRefresh:(BOOL)forceRefresh
- completion:(FSTVoidGetTokenResultBlock)completion {
- // Invalid token will force the GRPC fallback to use default settings.
- completion(Token::Invalid(), nil);
-}
-
-- (void)setUserChangeListener:(nullable FSTVoidUserBlock)block {
- // 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(User::Unauthenticated());
- }
-}
-
-- (nullable FSTVoidUserBlock)userChangeListener {
- // TODO(mikelehen): Implementation omitted for convenience since it's not actually required.
- FSTFail(@"Not implemented.");
-}
-
-@end
-
-NS_ASSUME_NONNULL_END
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<FSTCredentialsProvider>)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 <future>
+
#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<FSTCredentialsProvider>)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<FSTCredentialsProvider> 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<FSTCredentialsProvider>)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<FSTCredentialsProvider>)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<std::promise<User>>();
+
+ __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];
diff --git a/Firestore/Source/Remote/FSTDatastore.h b/Firestore/Source/Remote/FSTDatastore.h
index 481b6e8..7b8274c 100644
--- a/Firestore/Source/Remote/FSTDatastore.h
+++ b/Firestore/Source/Remote/FSTDatastore.h
@@ -18,6 +18,7 @@
#import "Firestore/Source/Core/FSTTypes.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 "absl/strings/string_view.h"
@@ -35,8 +36,6 @@
@class GRPCCall;
@class GRXWriter;
-@protocol FSTCredentialsProvider;
-
NS_ASSUME_NONNULL_BEGIN
/**
@@ -56,13 +55,15 @@ NS_ASSUME_NONNULL_BEGIN
/** Creates a new Datastore instance with the given database info. */
+ (instancetype)datastoreWithDatabase:(const firebase::firestore::core::DatabaseInfo *)databaseInfo
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials;
+ credentials:(firebase::firestore::auth::CredentialsProvider *)
+ credentials; // no passing ownership
- (instancetype)init __attribute__((unavailable("Use a static constructor method.")));
- (instancetype)initWithDatabaseInfo:(const firebase::firestore::core::DatabaseInfo *)databaseInfo
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(firebase::firestore::auth::CredentialsProvider *)
+ credentials // no passing ownership
NS_DESIGNATED_INITIALIZER;
/**
diff --git a/Firestore/Source/Remote/FSTDatastore.mm b/Firestore/Source/Remote/FSTDatastore.mm
index a6029ee..cb4516e 100644
--- a/Firestore/Source/Remote/FSTDatastore.mm
+++ b/Firestore/Source/Remote/FSTDatastore.mm
@@ -22,7 +22,6 @@
#import "FIRFirestoreErrors.h"
#import "Firestore/Source/API/FIRFirestore+Internal.h"
#import "Firestore/Source/API/FIRFirestoreVersion.h"
-#import "Firestore/Source/Auth/FSTCredentialsProvider.h"
#import "Firestore/Source/Local/FSTLocalStore.h"
#import "Firestore/Source/Model/FSTDocument.h"
#import "Firestore/Source/Model/FSTDocumentKey.h"
@@ -35,12 +34,15 @@
#import "Firestore/Protos/objc/google/firestore/v1beta1/Firestore.pbrpc.h"
+#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h"
#include "Firestore/core/src/firebase/firestore/auth/token.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/error_apple.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::Token;
using firebase::firestore::core::DatabaseInfo;
using firebase::firestore::model::DatabaseId;
@@ -70,8 +72,11 @@ typedef GRPCProtoCall * (^RPCFactory)(void);
@property(nonatomic, strong, readonly) FSTDispatchQueue *workerDispatchQueue;
-/** An object for getting an auth token before each request. */
-@property(nonatomic, strong, readonly) id<FSTCredentialsProvider> credentials;
+/**
+ * An object for getting an auth token before each request. Does not own the CredentialsProvider
+ * instance.
+ */
+@property(nonatomic, assign, readonly) CredentialsProvider *credentials;
@property(nonatomic, strong, readonly) FSTSerializerBeta *serializer;
@@ -81,7 +86,7 @@ typedef GRPCProtoCall * (^RPCFactory)(void);
+ (instancetype)datastoreWithDatabase:(const DatabaseInfo *)databaseInfo
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials {
+ credentials:(CredentialsProvider *)credentials {
return [[FSTDatastore alloc] initWithDatabaseInfo:databaseInfo
workerDispatchQueue:workerDispatchQueue
credentials:credentials];
@@ -89,7 +94,7 @@ typedef GRPCProtoCall * (^RPCFactory)(void);
- (instancetype)initWithDatabaseInfo:(const DatabaseInfo *)databaseInfo
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials {
+ credentials:(CredentialsProvider *)credentials {
if (self = [super init]) {
_databaseInfo = databaseInfo;
NSString *host = util::WrapNSStringNoCopy(databaseInfo->host());
@@ -301,24 +306,24 @@ typedef GRPCProtoCall * (^RPCFactory)(void);
errorHandler:(FSTVoidErrorBlock)errorHandler {
// TODO(mikelehen): We should force a refresh if the previous RPC failed due to an expired token,
// but I'm not sure how to detect that right now. http://b/32762461
- [self.credentials
- getTokenForcingRefresh:NO
- completion:^(Token result, NSError *_Nullable error) {
- error = [FSTDatastore firestoreErrorForError:error];
- [self.workerDispatchQueue dispatchAsyncAllowingSameQueue:^{
- if (error) {
- errorHandler(error);
- } else {
- GRPCProtoCall *rpc = rpcFactory();
- [FSTDatastore
- prepareHeadersForRPC:rpc
- databaseID:&self.databaseInfo->database_id()
- token:(result.is_valid() ? result.token()
- : absl::string_view())];
- [rpc start];
- }
- }];
- }];
+ _credentials->GetToken(
+ /*force_refresh=*/false,
+ [self, rpcFactory, errorHandler](Token result, const int64_t error_code,
+ const absl::string_view error_msg) {
+ NSError *error = util::WrapNSError(error_code, error_msg);
+ [self.workerDispatchQueue dispatchAsyncAllowingSameQueue:^{
+ if (error) {
+ errorHandler(error);
+ } else {
+ GRPCProtoCall *rpc = rpcFactory();
+ [FSTDatastore
+ prepareHeadersForRPC:rpc
+ databaseID:&self.databaseInfo->database_id()
+ token:(result.is_valid() ? result.token() : absl::string_view())];
+ [rpc start];
+ }
+ }];
+ });
}
- (FSTWatchStream *)createWatchStream {
diff --git a/Firestore/Source/Remote/FSTStream.h b/Firestore/Source/Remote/FSTStream.h
index 297d016..e48f1da 100644
--- a/Firestore/Source/Remote/FSTStream.h
+++ b/Firestore/Source/Remote/FSTStream.h
@@ -19,6 +19,7 @@
#import "Firestore/Source/Core/FSTTypes.h"
#import "Firestore/Source/Util/FSTDispatchQueue.h"
+#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h"
#include "Firestore/core/src/firebase/firestore/core/database_info.h"
@class FSTDocumentKey;
@@ -34,7 +35,6 @@
@class GRPCCall;
@class GRXWriter;
-@protocol FSTCredentialsProvider;
@protocol FSTWatchStreamDelegate;
@protocol FSTWriteStreamDelegate;
@@ -47,7 +47,7 @@ NS_ASSUME_NONNULL_BEGIN
*
* - Restarting a stream is allowed (after failure)
* - Exponential backoff on failure (independent of the underlying channel)
- * - Authentication via FSTCredentialsProvider
+ * - Authentication via CredentialsProvider
* - Dispatching all callbacks into the shared worker queue
*
* Subclasses of FSTStream implement serialization of models to and from bytes (via protocol
@@ -94,7 +94,7 @@ NS_ASSUME_NONNULL_BEGIN
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
connectionTimerID:(FSTTimerID)connectionTimerID
idleTimerID:(FSTTimerID)idleTimerID
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(firebase::firestore::auth::CredentialsProvider *)credentials // no passing ownership
responseMessageClass:(Class)responseMessageClass NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@@ -208,14 +208,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithDatabase:(const firebase::firestore::core::DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(firebase::firestore::auth::CredentialsProvider *)
+ credentials // no passsing ownership
serializer:(FSTSerializerBeta *)serializer NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDatabase:(const firebase::firestore::core::DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
connectionTimerID:(FSTTimerID)connectionTimerID
idleTimerID:(FSTTimerID)idleTimerID
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(firebase::firestore::auth::CredentialsProvider *)
+ credentials // no passing ownership
responseMessageClass:(Class)responseMessageClass NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
@@ -284,14 +286,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithDatabase:(const firebase::firestore::core::DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(firebase::firestore::auth::CredentialsProvider *)
+ credentials // no passing ownership
serializer:(FSTSerializerBeta *)serializer;
- (instancetype)initWithDatabase:(const firebase::firestore::core::DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
connectionTimerID:(FSTTimerID)connectionTimerID
idleTimerID:(FSTTimerID)idleTimerID
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(firebase::firestore::auth::CredentialsProvider *)
+ credentials // no passing ownership
responseMessageClass:(Class)responseMessageClass NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
diff --git a/Firestore/Source/Remote/FSTStream.mm b/Firestore/Source/Remote/FSTStream.mm
index a9aa245..6bec3ad 100644
--- a/Firestore/Source/Remote/FSTStream.mm
+++ b/Firestore/Source/Remote/FSTStream.mm
@@ -21,7 +21,6 @@
#import "FIRFirestoreErrors.h"
#import "Firestore/Source/API/FIRFirestore+Internal.h"
-#import "Firestore/Source/Auth/FSTCredentialsProvider.h"
#import "Firestore/Source/Local/FSTQueryData.h"
#import "Firestore/Source/Model/FSTMutation.h"
#import "Firestore/Source/Remote/FSTBufferedWriter.h"
@@ -38,9 +37,11 @@
#include "Firestore/core/src/firebase/firestore/auth/token.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/error_apple.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::Token;
using firebase::firestore::core::DatabaseInfo;
using firebase::firestore::model::DatabaseId;
@@ -103,12 +104,12 @@ typedef NS_ENUM(NSInteger, FSTStreamState) {
*/
- (instancetype)initWithDatabase:(const DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(CredentialsProvider *)credentials
serializer:(FSTSerializerBeta *)serializer NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDatabase:(const DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(CredentialsProvider *)credentials
responseMessageClass:(Class)responseMessageClass NS_UNAVAILABLE;
@end
@@ -126,7 +127,7 @@ typedef NS_ENUM(NSInteger, FSTStreamState) {
// Does not own this DatabaseInfo.
@property(nonatomic, assign, readonly) const DatabaseInfo *databaseInfo;
@property(nonatomic, strong, readonly) FSTDispatchQueue *workerDispatchQueue;
-@property(nonatomic, strong, readonly) id<FSTCredentialsProvider> credentials;
+@property(nonatomic, assign, readonly) CredentialsProvider *credentials;
@property(nonatomic, unsafe_unretained, readonly) Class responseMessageClass;
@property(nonatomic, strong, readonly) FSTExponentialBackoff *backoff;
@@ -213,7 +214,7 @@ static const NSTimeInterval kIdleTimeout = 60.0;
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
connectionTimerID:(FSTTimerID)connectionTimerID
idleTimerID:(FSTTimerID)idleTimerID
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(CredentialsProvider *)credentials
responseMessageClass:(Class)responseMessageClass {
if (self = [super init]) {
_databaseInfo = database;
@@ -263,13 +264,14 @@ static const NSTimeInterval kIdleTimeout = 60.0;
FSTAssert(_delegate == nil, @"Delegate must be nil");
_delegate = delegate;
- [self.credentials getTokenForcingRefresh:NO
- completion:^(Token result, NSError *_Nullable error) {
- error = [FSTDatastore firestoreErrorForError:error];
- [self.workerDispatchQueue dispatchAsyncAllowingSameQueue:^{
- [self resumeStartWithToken:result error:error];
- }];
- }];
+ _credentials->GetToken(
+ /*force_refresh=*/false,
+ [self](Token result, const int64_t error_code, const absl::string_view error_msg) {
+ NSError *error = util::WrapNSError(error_code, error_msg);
+ [self.workerDispatchQueue dispatchAsyncAllowingSameQueue:^{
+ [self resumeStartWithToken:result error:error];
+ }];
+ });
}
/** Add an access token to our RPC, after obtaining one from the credentials provider. */
@@ -614,7 +616,7 @@ static const NSTimeInterval kIdleTimeout = 60.0;
- (instancetype)initWithDatabase:(const DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(CredentialsProvider *)credentials
serializer:(FSTSerializerBeta *)serializer {
self = [super initWithDatabase:database
workerDispatchQueue:workerDispatchQueue
@@ -699,7 +701,7 @@ static const NSTimeInterval kIdleTimeout = 60.0;
- (instancetype)initWithDatabase:(const DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(CredentialsProvider *)credentials
serializer:(FSTSerializerBeta *)serializer {
self = [super initWithDatabase:database
workerDispatchQueue:workerDispatchQueue