aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar zxu <zxu@google.com>2018-02-27 14:04:39 -0500
committerGravatar GitHub <noreply@github.com>2018-02-27 14:04:39 -0500
commit3e7c062f3baca83fae1937bf60865be0cd18f96d (patch)
treeb9816a635f0deda9601496b0d41f6b064f99d838
parent13aeb61de4fac4c0239bcf44a98a7d3aa9203963 (diff)
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 <utility> for std::move * Use std::future for the initial user * fix style
-rw-r--r--Firestore/Example/Tests/Integration/FSTDatastoreTests.mm9
-rw-r--r--Firestore/Example/Tests/Integration/FSTStreamTests.mm10
-rw-r--r--Firestore/Example/Tests/SpecTests/FSTMockDatastore.h2
-rw-r--r--Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm35
-rw-r--r--Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm14
-rw-r--r--Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm20
-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
-rw-r--r--Firestore/core/include/firebase/firestore/firestore_errors.h115
-rw-r--r--Firestore/core/src/firebase/firestore/auth/credentials_provider.h7
-rw-r--r--Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc3
-rw-r--r--Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm7
-rw-r--r--Firestore/core/src/firebase/firestore/util/error_apple.h52
-rw-r--r--Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc7
-rw-r--r--Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc8
-rw-r--r--Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm12
26 files changed, 360 insertions, 470 deletions
diff --git a/Firestore/Example/Tests/Integration/FSTDatastoreTests.mm b/Firestore/Example/Tests/Integration/FSTDatastoreTests.mm
index c38e8f3..4323ccd 100644
--- a/Firestore/Example/Tests/Integration/FSTDatastoreTests.mm
+++ b/Firestore/Example/Tests/Integration/FSTDatastoreTests.mm
@@ -23,7 +23,6 @@
#import "Firestore/Source/API/FIRDocumentReference+Internal.h"
#import "Firestore/Source/API/FSTUserDataConverter.h"
-#import "Firestore/Source/Auth/FSTEmptyCredentialsProvider.h"
#import "Firestore/Source/Core/FSTFirestoreClient.h"
#import "Firestore/Source/Core/FSTQuery.h"
#import "Firestore/Source/Core/FSTSnapshotVersion.h"
@@ -41,11 +40,13 @@
#import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
+#include "Firestore/core/src/firebase/firestore/auth/empty_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::EmptyCredentialsProvider;
using firebase::firestore::core::DatabaseInfo;
using firebase::firestore::model::DatabaseId;
@@ -141,7 +142,7 @@ NS_ASSUME_NONNULL_BEGIN
@implementation FSTDatastoreTests {
FSTDispatchQueue *_testWorkerQueue;
FSTLocalStore *_localStore;
- id<FSTCredentialsProvider> _credentials;
+ EmptyCredentialsProvider _credentials;
DatabaseInfo _databaseInfo;
FSTDatastore *_datastore;
@@ -170,11 +171,9 @@ NS_ASSUME_NONNULL_BEGIN
queueWith:dispatch_queue_create("com.google.firestore.FSTDatastoreTestsWorkerQueue",
DISPATCH_QUEUE_SERIAL)];
- _credentials = [[FSTEmptyCredentialsProvider alloc] init];
-
_datastore = [FSTDatastore datastoreWithDatabase:&_databaseInfo
workerDispatchQueue:_testWorkerQueue
- credentials:_credentials];
+ credentials:&_credentials];
_remoteStore = [FSTRemoteStore remoteStoreWithLocalStore:_localStore datastore:_datastore];
diff --git a/Firestore/Example/Tests/Integration/FSTStreamTests.mm b/Firestore/Example/Tests/Integration/FSTStreamTests.mm
index 9105b74..6550368 100644
--- a/Firestore/Example/Tests/Integration/FSTStreamTests.mm
+++ b/Firestore/Example/Tests/Integration/FSTStreamTests.mm
@@ -22,16 +22,17 @@
#import "Firestore/Example/Tests/Util/FSTHelpers.h"
#import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
-#import "Firestore/Source/Auth/FSTEmptyCredentialsProvider.h"
#import "Firestore/Source/Remote/FSTDatastore.h"
#import "Firestore/Source/Remote/FSTStream.h"
#import "Firestore/Source/Util/FSTAssert.h"
+#include "Firestore/core/src/firebase/firestore/auth/empty_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::EmptyCredentialsProvider;
using firebase::firestore::core::DatabaseInfo;
using firebase::firestore::model::DatabaseId;
@@ -136,7 +137,7 @@ using firebase::firestore::model::DatabaseId;
dispatch_queue_t _testQueue;
FSTDispatchQueue *_workerDispatchQueue;
DatabaseInfo _databaseInfo;
- FSTEmptyCredentialsProvider *_credentials;
+ EmptyCredentialsProvider _credentials;
FSTStreamStatusDelegate *_delegate;
/** Single mutation to send to the write stream. */
@@ -155,7 +156,6 @@ using firebase::firestore::model::DatabaseId;
_databaseInfo = DatabaseInfo(database_id, "test-key", util::MakeStringView(settings.host),
settings.sslEnabled);
- _credentials = [[FSTEmptyCredentialsProvider alloc] init];
_delegate = [[FSTStreamStatusDelegate alloc] initWithTestCase:self queue:_workerDispatchQueue];
@@ -165,14 +165,14 @@ using firebase::firestore::model::DatabaseId;
- (FSTWriteStream *)setUpWriteStream {
FSTDatastore *datastore = [[FSTDatastore alloc] initWithDatabaseInfo:&_databaseInfo
workerDispatchQueue:_workerDispatchQueue
- credentials:_credentials];
+ credentials:&_credentials];
return [datastore createWriteStream];
}
- (FSTWatchStream *)setUpWatchStream {
FSTDatastore *datastore = [[FSTDatastore alloc] initWithDatabaseInfo:&_databaseInfo
workerDispatchQueue:_workerDispatchQueue
- credentials:_credentials];
+ credentials:&_credentials];
return [datastore createWatchStream];
}
diff --git a/Firestore/Example/Tests/SpecTests/FSTMockDatastore.h b/Firestore/Example/Tests/SpecTests/FSTMockDatastore.h
index 5420c2e..e1ea2fb 100644
--- a/Firestore/Example/Tests/SpecTests/FSTMockDatastore.h
+++ b/Firestore/Example/Tests/SpecTests/FSTMockDatastore.h
@@ -34,8 +34,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property(nonatomic) int writeStreamRequestCount;
-+ (instancetype)mockDatastoreWithWorkerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue;
-
#pragma mark - Watch Stream manipulation.
/** Injects an Added WatchChange containing the given targetIDs. */
diff --git a/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm b/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm
index d3c4171..6715b24 100644
--- a/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm
+++ b/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm
@@ -16,7 +16,6 @@
#import "Firestore/Example/Tests/SpecTests/FSTMockDatastore.h"
-#import "Firestore/Source/Auth/FSTEmptyCredentialsProvider.h"
#import "Firestore/Source/Core/FSTSnapshotVersion.h"
#import "Firestore/Source/Local/FSTQueryData.h"
#import "Firestore/Source/Model/FSTMutation.h"
@@ -27,10 +26,14 @@
#import "Firestore/Example/Tests/Remote/FSTWatchChange+Testing.h"
+#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h"
+#include "Firestore/core/src/firebase/firestore/auth/empty_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"
+using firebase::firestore::auth::CredentialsProvider;
+using firebase::firestore::auth::EmptyCredentialsProvider;
using firebase::firestore::core::DatabaseInfo;
using firebase::firestore::model::DatabaseId;
@@ -44,17 +47,17 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithDatastore:(FSTMockDatastore *)datastore
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
serializer:(FSTSerializerBeta *)serializer NS_UNAVAILABLE;
- (instancetype)initWithDatabase:(const DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(CredentialsProvider *)credentials
responseMessageClass:(Class)responseMessageClass NS_UNAVAILABLE;
@property(nonatomic, assign) BOOL open;
@@ -69,7 +72,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithDatastore:(FSTMockDatastore *)datastore
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(CredentialsProvider *)credentials
serializer:(FSTSerializerBeta *)serializer {
self = [super initWithDatabase:datastore.databaseInfo
workerDispatchQueue:workerDispatchQueue
@@ -170,17 +173,17 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithDatastore:(FSTMockDatastore *)datastore
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
serializer:(FSTSerializerBeta *)serializer NS_UNAVAILABLE;
- (instancetype)initWithDatabase:(const DatabaseInfo *)database
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(CredentialsProvider *)credentials
responseMessageClass:(Class)responseMessageClass NS_UNAVAILABLE;
@property(nonatomic, strong, readonly) FSTMockDatastore *datastore;
@@ -193,7 +196,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithDatastore:(FSTMockDatastore *)datastore
workerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue
- credentials:(id<FSTCredentialsProvider>)credentials
+ credentials:(CredentialsProvider *)credentials
serializer:(FSTSerializerBeta *)serializer {
self = [super initWithDatabase:datastore.databaseInfo
workerDispatchQueue:workerDispatchQueue
@@ -279,24 +282,12 @@ NS_ASSUME_NONNULL_BEGIN
/** Properties implemented in FSTDatastore that are nonpublic. */
@property(nonatomic, strong, readonly) FSTDispatchQueue *workerDispatchQueue;
-@property(nonatomic, strong, readonly) id<FSTCredentialsProvider> credentials;
+@property(nonatomic, assign, readonly) CredentialsProvider *credentials;
@end
@implementation FSTMockDatastore
-+ (instancetype)mockDatastoreWithWorkerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue {
- // This owns the DatabaseInfos since we do not have FirestoreClient instance to own them.
- static DatabaseInfo database_info{DatabaseId{"project", "database"}, "persistence", "host",
- false};
-
- FSTEmptyCredentialsProvider *credentials = [[FSTEmptyCredentialsProvider alloc] init];
-
- return [[FSTMockDatastore alloc] initWithDatabaseInfo:&database_info
- workerDispatchQueue:workerDispatchQueue
- credentials:credentials];
-}
-
#pragma mark - Overridden FSTDatastore methods.
- (FSTWatchStream *)createWatchStream {
diff --git a/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm b/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm
index 1c7eadf..07dc84f 100644
--- a/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm
+++ b/Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm
@@ -37,10 +37,16 @@
#import "Firestore/Example/Tests/Core/FSTSyncEngine+Testing.h"
#import "Firestore/Example/Tests/SpecTests/FSTMockDatastore.h"
+#include "Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.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"
+using firebase::firestore::auth::EmptyCredentialsProvider;
using firebase::firestore::auth::HashUser;
using firebase::firestore::auth::User;
+using firebase::firestore::core::DatabaseInfo;
+using firebase::firestore::model::DatabaseId;
NS_ASSUME_NONNULL_BEGIN
@@ -83,7 +89,9 @@ NS_ASSUME_NONNULL_BEGIN
// ivar is declared as mutable.
std::unordered_map<User, NSMutableArray<FSTOutstandingWrite *> *, HashUser> _outstandingWrites;
+ DatabaseInfo _databaseInfo;
User _currentUser;
+ EmptyCredentialsProvider _credentialProvider;
}
- (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
@@ -106,13 +114,17 @@ NS_ASSUME_NONNULL_BEGIN
_events = [NSMutableArray array];
+ _databaseInfo = {DatabaseId{"project", "database"}, "persistence", "host", false};
+
// Set up the sync engine and various stores.
dispatch_queue_t mainQueue = dispatch_get_main_queue();
FSTDispatchQueue *dispatchQueue = [FSTDispatchQueue queueWith:mainQueue];
_localStore = [[FSTLocalStore alloc] initWithPersistence:persistence
garbageCollector:garbageCollector
initialUser:initialUser];
- _datastore = [FSTMockDatastore mockDatastoreWithWorkerDispatchQueue:dispatchQueue];
+ _datastore = [[FSTMockDatastore alloc] initWithDatabaseInfo:&_databaseInfo
+ workerDispatchQueue:dispatchQueue
+ credentials:&_credentialProvider];
_remoteStore = [FSTRemoteStore remoteStoreWithLocalStore:_localStore datastore:_datastore];
diff --git a/Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm b/Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm
index 3c80d16..059f257 100644
--- a/Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm
+++ b/Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm
@@ -16,25 +16,30 @@
#import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
+#include <memory>
+#include <utility>
+
#import <FirebaseCore/FIRLogger.h>
#import <FirebaseFirestore/FirebaseFirestore-umbrella.h>
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Tests.h>
+#include "Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.h"
+#include "Firestore/core/src/firebase/firestore/model/database_id.h"
#include "Firestore/core/src/firebase/firestore/util/autoid.h"
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+#include "absl/memory/memory.h"
#import "Firestore/Source/API/FIRFirestore+Internal.h"
-#import "Firestore/Source/Auth/FSTEmptyCredentialsProvider.h"
#import "Firestore/Source/Core/FSTFirestoreClient.h"
#import "Firestore/Source/Local/FSTLevelDB.h"
#import "Firestore/Source/Util/FSTDispatchQueue.h"
#import "Firestore/Example/Tests/Util/FSTEventAccumulator.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::EmptyCredentialsProvider;
using firebase::firestore::model::DatabaseId;
using firebase::firestore::util::CreateAutoId;
@@ -135,15 +140,16 @@ NS_ASSUME_NONNULL_BEGIN
FSTDispatchQueue *workerDispatchQueue = [FSTDispatchQueue
queueWith:dispatch_queue_create("com.google.firebase.firestore", DISPATCH_QUEUE_SERIAL)];
- FSTEmptyCredentialsProvider *credentialsProvider = [[FSTEmptyCredentialsProvider alloc] init];
-
FIRSetLoggerLevel(FIRLoggerLevelDebug);
// HACK: FIRFirestore expects a non-nil app, but for tests we cheat.
FIRApp *app = nil;
+ std::unique_ptr<CredentialsProvider> credentials_provider =
+ absl::make_unique<firebase::firestore::auth::EmptyCredentialsProvider>();
+
FIRFirestore *firestore = [[FIRFirestore alloc] initWithProjectID:util::MakeStringView(projectID)
database:DatabaseId::kDefault
persistenceKey:persistenceKey
- credentialsProvider:credentialsProvider
+ credentialsProvider:std::move(credentials_provider)
workerDispatchQueue:workerDispatchQueue
firebaseApp:app];
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
diff --git a/Firestore/core/include/firebase/firestore/firestore_errors.h b/Firestore/core/include/firebase/firestore/firestore_errors.h
new file mode 100644
index 0000000..7a0ff7c
--- /dev/null
+++ b/Firestore/core/include/firebase/firestore/firestore_errors.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#ifndef FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_ERRORS_H_
+#define FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_ERRORS_H_
+
+namespace firebase {
+namespace firestore {
+
+/**
+ * Error codes used by Cloud Firestore.
+ *
+ * The codes are in sync with the Firestore iOS client SDK header file
+ * FIRFirestoreErrors.h.
+ */
+enum FirestoreErrorCode {
+ /**
+ * The operation completed successfully. NSError objects will never have a
+ * code with this value.
+ */
+ Ok = 0,
+
+ /** The operation was cancelled (typically by the caller). */
+ Cancelled = 1,
+
+ /** Unknown error or an error from a different error domain. */
+ Unknown = 2,
+
+ /**
+ * Client specified an invalid argument. Note that this differs from
+ * FailedPrecondition. InvalidArgument indicates arguments that are
+ * problematic regardless of the state of the system (e.g., an invalid field
+ * name).
+ */
+ InvalidArgument = 3,
+
+ /**
+ * Deadline expired before operation could complete. For operations that
+ * change the state of the system, this error may be returned even if the
+ * operation has completed successfully. For example, a successful response
+ * from a server could have been delayed long enough for the deadline to
+ * expire.
+ */
+ DeadlineExceeded = 4,
+
+ /** Some requested document was not found. */
+ NotFound = 5,
+
+ /** Some document that we attempted to create already exists. */
+ AlreadyExists = 6,
+
+ /** The caller does not have permission to execute the specified operation. */
+ PermissionDenied = 7,
+
+ /**
+ * Some resource has been exhausted, perhaps a per-user quota, or perhaps the
+ * entire file system is out of space.
+ */
+ ResourceExhausted = 8,
+
+ /**
+ * Operation was rejected because the system is not in a state required for
+ * the operation's execution.
+ */
+ FailedPrecondition = 9,
+
+ /**
+ * The operation was aborted, typically due to a concurrency issue like
+ * transaction aborts, etc.
+ */
+ Aborted = 10,
+
+ /** Operation was attempted past the valid range. */
+ OutOfRange = 11,
+
+ /** Operation is not implemented or not supported/enabled. */
+ Unimplemented = 12,
+
+ /**
+ * Internal errors. Means some invariants expected by underlying system has
+ * been broken. If you see one of these errors, something is very broken.
+ */
+ Internal = 13,
+
+ /**
+ * The service is currently unavailable. This is a most likely a transient
+ * condition and may be corrected by retrying with a backoff.
+ */
+ Unavailable = 14,
+
+ /** Unrecoverable data loss or corruption. */
+ DataLoss = 15,
+
+ /** The request does not have valid authentication credentials for the
+ operation. */
+ Unauthenticated = 16
+};
+
+} // namespace firestore
+} // namespace firebase
+
+#endif // FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_ERRORS_H_
diff --git a/Firestore/core/src/firebase/firestore/auth/credentials_provider.h b/Firestore/core/src/firebase/firestore/auth/credentials_provider.h
index 917f8e1..b9a8a24 100644
--- a/Firestore/core/src/firebase/firestore/auth/credentials_provider.h
+++ b/Firestore/core/src/firebase/firestore/auth/credentials_provider.h
@@ -20,6 +20,7 @@
#include <functional>
#include <string>
+#include "Firestore/core/include/firebase/firestore/firestore_errors.h"
#include "Firestore/core/src/firebase/firestore/auth/token.h"
#include "Firestore/core/src/firebase/firestore/auth/user.h"
#include "absl/strings/string_view.h"
@@ -30,8 +31,10 @@ namespace auth {
// `TokenErrorListener` is a listener that gets a token or an error.
// token: An auth token as a string, or nullptr if error occurred.
-// error: The error if one occurred, or else nullptr.
-typedef std::function<void(Token token, const absl::string_view error)>
+// error_code: The error code if one occurred, or else FirestoreErrorCode::Ok.
+// error_msg: The error if one occurred, or else nullptr.
+typedef std::function<void(
+ Token token, const int64_t error_code, const absl::string_view error_msg)>
TokenListener;
// Listener notified with a User change.
diff --git a/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc b/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc
index 6ee7f61..0fa70c0 100644
--- a/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc
+++ b/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc
@@ -26,7 +26,8 @@ void EmptyCredentialsProvider::GetToken(bool force_refresh,
TokenListener completion) {
UNUSED(force_refresh);
if (completion) {
- completion({"", User::Unauthenticated()}, "");
+ // Invalid token will force the GRPC fallback to use default settings.
+ completion(Token::Invalid(), FirestoreErrorCode::Ok, "");
}
}
diff --git a/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm b/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm
index fe3cb24..1babe82 100644
--- a/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm
+++ b/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm
@@ -53,7 +53,7 @@ FirebaseCredentialsProvider::FirebaseCredentialsProvider(FIRApp* app)
NSString* user_id =
user_info[FIRAuthStateDidChangeInternalNotificationUIDKey];
- User new_user(util::MakeStringView(user_id));
+ User new_user = User::FromUid(user_id);
if (new_user != contents->current_user) {
contents->current_user = new_user;
contents->user_counter++;
@@ -96,11 +96,12 @@ void FirebaseCredentialsProvider::GetToken(bool force_refresh,
// 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).
- completion({"", User::Unauthenticated()},
+ completion(Token::Invalid(), FirestoreErrorCode::Aborted,
"getToken aborted due to user change.");
} else {
completion(
- {util::MakeStringView(token), contents->current_user},
+ Token{util::MakeStringView(token), contents->current_user},
+ error == nil ? FirestoreErrorCode::Ok : error.code,
error == nil ? "" : util::MakeStringView(error.localizedDescription));
}
};
diff --git a/Firestore/core/src/firebase/firestore/util/error_apple.h b/Firestore/core/src/firebase/firestore/util/error_apple.h
new file mode 100644
index 0000000..e31cfd6
--- /dev/null
+++ b/Firestore/core/src/firebase/firestore/util/error_apple.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ERROR_APPLE_H_
+#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ERROR_APPLE_H_
+
+// Everything in this header exists for compatibility with Objective-C.
+#if __OBJC__
+
+#import <Foundation/Foundation.h>
+
+#include "Firestore/Source/Public/FIRFirestoreErrors.h" // for FIRFirestoreErrorDomain
+#include "Firestore/core/include/firebase/firestore/firestore_errors.h"
+#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
+#include "absl/strings/string_view.h"
+
+namespace firebase {
+namespace firestore {
+namespace util {
+
+// Translates a set of error_code and error_msg to an NSError.
+inline NSError* WrapNSError(const int64_t error_code,
+ const absl::string_view error_msg) {
+ if (error_code == FirestoreErrorCode::Ok) {
+ return nil;
+ }
+ return [NSError
+ errorWithDomain:FIRFirestoreErrorDomain
+ code:error_code
+ userInfo:@{NSLocalizedDescriptionKey : WrapNSString(error_msg)}];
+}
+
+} // namespace util
+} // namespace firestore
+} // namespace firebase
+
+#endif // __OBJC__
+
+#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ERROR_APPLE_H_
diff --git a/Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc b/Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc
index 9ae71ba..6895061 100644
--- a/Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc
+++ b/Firestore/core/test/firebase/firestore/auth/credentials_provider_test.cc
@@ -25,10 +25,11 @@ namespace auth {
#define UNUSED(x) (void)(x)
TEST(CredentialsProvider, Typedef) {
- TokenListener token_listener = [](Token token,
- const absl::string_view error) {
+ TokenListener token_listener = [](Token token, const int64_t error_code,
+ const absl::string_view error_msg) {
UNUSED(token);
- UNUSED(error);
+ UNUSED(error_code);
+ UNUSED(error_msg);
};
EXPECT_NE(nullptr, token_listener);
EXPECT_TRUE(token_listener);
diff --git a/Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc b/Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc
index 39012f0..3b487f3 100644
--- a/Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc
+++ b/Firestore/core/test/firebase/firestore/auth/empty_credentials_provider_test.cc
@@ -25,12 +25,14 @@ namespace auth {
TEST(EmptyCredentialsProvider, GetToken) {
EmptyCredentialsProvider credentials_provider;
credentials_provider.GetToken(
- /*force_refresh=*/true, [](Token token, const absl::string_view error) {
- EXPECT_EQ("", token.token());
+ /*force_refresh=*/true, [](Token token, const int64_t error_code,
+ const absl::string_view error_msg) {
+ EXPECT_FALSE(token.is_valid());
const User& user = token.user();
EXPECT_EQ("", user.uid());
EXPECT_FALSE(user.is_authenticated());
- EXPECT_EQ("", error);
+ EXPECT_EQ(FirestoreErrorCode::Ok, error_code);
+ EXPECT_EQ("", error_msg);
});
}
diff --git a/Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm b/Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm
index a6ccc4a..3660d53 100644
--- a/Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm
+++ b/Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm
@@ -42,12 +42,14 @@ TEST(FirebaseCredentialsProviderTest, GetTokenUnauthenticated) {
FirebaseCredentialsProvider credentials_provider(app);
credentials_provider.GetToken(
- /*force_refresh=*/true, [](Token token, const absl::string_view error) {
+ /*force_refresh=*/true, [](Token token, const int64_t error_code,
+ const absl::string_view error_msg) {
EXPECT_EQ("", token.token());
const User& user = token.user();
EXPECT_EQ("", user.uid());
EXPECT_FALSE(user.is_authenticated());
- EXPECT_EQ("", error) << error;
+ EXPECT_EQ(FirestoreErrorCode::Ok, error_code) << error_code;
+ EXPECT_EQ("", error_msg) << error_msg;
});
}
@@ -56,12 +58,14 @@ TEST(FirebaseCredentialsProviderTest, GetToken) {
FirebaseCredentialsProvider credentials_provider(app);
credentials_provider.GetToken(
- /*force_refresh=*/true, [](Token token, const absl::string_view error) {
+ /*force_refresh=*/true, [](Token token, const int64_t error_code,
+ const absl::string_view error_msg) {
EXPECT_EQ("", token.token());
const User& user = token.user();
EXPECT_EQ("fake uid", user.uid());
EXPECT_TRUE(user.is_authenticated());
- EXPECT_EQ("", error) << error;
+ EXPECT_EQ(FirestoreErrorCode::Ok, error_code) << error_code;
+ EXPECT_EQ("", error_msg) << error_msg;
});
}