Skip to content

Commit 8df9ab4

Browse files
wilhuffzxu123
authored andcommitted
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
1 parent c4a8336 commit 8df9ab4

File tree

6 files changed

+41
-43
lines changed

6 files changed

+41
-43
lines changed

Firestore/Example/Tests/SpecTests/FSTMockDatastore.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ NS_ASSUME_NONNULL_BEGIN
3434
*/
3535
@property(nonatomic) int writeStreamRequestCount;
3636

37-
+ (instancetype)mockDatastoreWithWorkerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue;
38-
3937
#pragma mark - Watch Stream manipulation.
4038

4139
/** Injects an Added WatchChange containing the given targetIDs. */

Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
#import "Firestore/Example/Tests/SpecTests/FSTMockDatastore.h"
1818

19-
#include <list>
20-
2119
#import "Firestore/Source/Core/FSTSnapshotVersion.h"
2220
#import "Firestore/Source/Local/FSTQueryData.h"
2321
#import "Firestore/Source/Model/FSTMutation.h"
@@ -290,20 +288,6 @@ @interface FSTMockDatastore ()
290288

291289
@implementation FSTMockDatastore
292290

293-
+ (instancetype)mockDatastoreWithWorkerDispatchQueue:(FSTDispatchQueue *)workerDispatchQueue {
294-
// This owns the DatabaseInfos since we do not have FirestoreClient instance to own them.
295-
static DatabaseInfo database_info{DatabaseId{"project", "database"}, "persistence", "host",
296-
false};
297-
298-
// Note that we purposely don't bother to cleanup the EmptyCredentialsProvider instances.
299-
static std::list<EmptyCredentialsProvider> credentials_providers;
300-
credentials_providers.emplace_back();
301-
302-
return [[FSTMockDatastore alloc] initWithDatabaseInfo:&database_info
303-
workerDispatchQueue:workerDispatchQueue
304-
credentials:&credentials_providers.back()];
305-
}
306-
307291
#pragma mark - Overridden FSTDatastore methods.
308292

309293
- (FSTWatchStream *)createWatchStream {

Firestore/Example/Tests/SpecTests/FSTSyncEngineTestDriver.mm

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,16 @@
3737
#import "Firestore/Example/Tests/Core/FSTSyncEngine+Testing.h"
3838
#import "Firestore/Example/Tests/SpecTests/FSTMockDatastore.h"
3939

40+
#include "Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.h"
4041
#include "Firestore/core/src/firebase/firestore/auth/user.h"
42+
#include "Firestore/core/src/firebase/firestore/core/database_info.h"
43+
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
4144

45+
using firebase::firestore::auth::EmptyCredentialsProvider;
4246
using firebase::firestore::auth::HashUser;
4347
using firebase::firestore::auth::User;
48+
using firebase::firestore::core::DatabaseInfo;
49+
using firebase::firestore::model::DatabaseId;
4450

4551
NS_ASSUME_NONNULL_BEGIN
4652

@@ -83,7 +89,9 @@ @implementation FSTSyncEngineTestDriver {
8389
// ivar is declared as mutable.
8490
std::unordered_map<User, NSMutableArray<FSTOutstandingWrite *> *, HashUser> _outstandingWrites;
8591

92+
DatabaseInfo _databaseInfo;
8693
User _currentUser;
94+
EmptyCredentialsProvider _credentialProvider;
8795
}
8896

8997
- (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
@@ -106,13 +114,17 @@ - (instancetype)initWithPersistence:(id<FSTPersistence>)persistence
106114

107115
_events = [NSMutableArray array];
108116

117+
_databaseInfo = {DatabaseId{"project", "database"}, "persistence", "host", false};
118+
109119
// Set up the sync engine and various stores.
110120
dispatch_queue_t mainQueue = dispatch_get_main_queue();
111121
FSTDispatchQueue *dispatchQueue = [FSTDispatchQueue queueWith:mainQueue];
112122
_localStore = [[FSTLocalStore alloc] initWithPersistence:persistence
113123
garbageCollector:garbageCollector
114124
initialUser:initialUser];
115-
_datastore = [FSTMockDatastore mockDatastoreWithWorkerDispatchQueue:dispatchQueue];
125+
_datastore = [[FSTMockDatastore alloc] initWithDatabaseInfo:&_databaseInfo
126+
workerDispatchQueue:dispatchQueue
127+
credentials:&_credentialProvider];
116128

117129
_remoteStore = [FSTRemoteStore remoteStoreWithLocalStore:_localStore datastore:_datastore];
118130

Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
1818

1919
#include <memory>
20+
#include <utility>
2021

2122
#import <FirebaseCore/FIRLogger.h>
2223
#import <FirebaseFirestore/FirebaseFirestore-umbrella.h>
@@ -27,6 +28,7 @@
2728
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
2829
#include "Firestore/core/src/firebase/firestore/util/autoid.h"
2930
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
31+
#include "absl/memory/memory.h"
3032

3133
#import "Firestore/Source/API/FIRFirestore+Internal.h"
3234
#import "Firestore/Source/Core/FSTFirestoreClient.h"
@@ -141,7 +143,9 @@ - (FIRFirestore *)firestoreWithProjectID:(NSString *)projectID {
141143
FIRSetLoggerLevel(FIRLoggerLevelDebug);
142144
// HACK: FIRFirestore expects a non-nil app, but for tests we cheat.
143145
FIRApp *app = nil;
144-
std::unique_ptr<CredentialsProvider> credentials_provider(new EmptyCredentialsProvider());
146+
std::unique_ptr<CredentialsProvider> credentials_provider =
147+
absl::make_unique<firebase::firestore::auth::EmptyCredentialsProvider>();
148+
145149
FIRFirestore *firestore = [[FIRFirestore alloc] initWithProjectID:util::MakeStringView(projectID)
146150
database:DatabaseId::kDefault
147151
persistenceKey:persistenceKey

Firestore/Source/API/FIRFirestore.mm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#import "FIRFirestore.h"
1818

1919
#include <memory>
20+
#include <utility>
2021

2122
#import <FirebaseCore/FIRApp.h>
2223
#import <FirebaseCore/FIRAppInternal.h>
@@ -44,6 +45,7 @@
4445
#include "Firestore/core/src/firebase/firestore/core/database_info.h"
4546
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
4647
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
48+
#include "absl/memory/memory.h"
4749

4850
namespace util = firebase::firestore::util;
4951
using firebase::firestore::auth::CredentialsProvider;
@@ -159,7 +161,7 @@ + (instancetype)firestoreForApp:(FIRApp *)app database:(NSString *)database {
159161
queueWith:dispatch_queue_create("com.google.firebase.firestore", DISPATCH_QUEUE_SERIAL)];
160162

161163
std::unique_ptr<CredentialsProvider> credentials_provider =
162-
std::make_unique<FirebaseCredentialsProvider>(app);
164+
absl::make_unique<FirebaseCredentialsProvider>(app);
163165

164166
NSString *persistenceKey = app.name;
165167

Firestore/Source/Core/FSTFirestoreClient.mm

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#import "Firestore/Source/Core/FSTFirestoreClient.h"
1818

19+
#import <future>
20+
1921
#import "Firestore/Source/Core/FSTEventManager.h"
2022
#import "Firestore/Source/Core/FSTSyncEngine.h"
2123
#import "Firestore/Source/Core/FSTTransaction.h"
@@ -104,35 +106,31 @@ - (instancetype)initWithDatabaseInfo:(const DatabaseInfo &)databaseInfo
104106
_userDispatchQueue = userDispatchQueue;
105107
_workerDispatchQueue = workerDispatchQueue;
106108

107-
dispatch_semaphore_t initialUserAvailable = dispatch_semaphore_create(0);
108-
__block bool initialized = false;
109-
__block User initialUser;
110-
FSTWeakify(self);
111-
auto userChangeListener = ^(User user) {
112-
FSTStrongify(self);
113-
if (self) {
114-
if (!initialized) {
115-
initialUser = user;
116-
initialized = true;
117-
dispatch_semaphore_signal(initialUserAvailable);
118-
} else {
119-
[workerDispatchQueue dispatchAsync:^{
120-
[self userDidChange:user];
121-
}];
122-
}
109+
auto userPromise = std::make_shared<std::promise<User>>();
110+
111+
__weak typeof(self) weakSelf = self;
112+
auto userChangeListener = [initialized = false, userPromise, weakSelf, workerDispatchQueue](User user) mutable {
113+
typeof(self) strongSelf = weakSelf;
114+
if (!strongSelf) return;
115+
116+
if (!initialized) {
117+
initialized = true;
118+
userPromise->set_value(user);
119+
} else {
120+
[workerDispatchQueue dispatchAsync:^{
121+
[strongSelf userDidChange:user];
122+
}];
123123
}
124124
};
125125

126-
_credentialsProvider->SetUserChangeListener(
127-
[userChangeListener](const User &user) { userChangeListener(user); });
126+
_credentialsProvider->SetUserChangeListener(userChangeListener);
128127

129128
// Defer initialization until we get the current user from the userChangeListener. This is
130129
// guaranteed to be synchronously dispatched onto our worker queue, so we will be initialized
131130
// before any subsequently queued work runs.
132131
[_workerDispatchQueue dispatchAsync:^{
133-
dispatch_semaphore_wait(initialUserAvailable, DISPATCH_TIME_FOREVER);
134-
135-
[self initializeWithUser:initialUser usePersistence:usePersistence];
132+
User user = userPromise->get_future().get();
133+
[self initializeWithUser:user usePersistence:usePersistence];
136134
}];
137135
}
138136
return self;
@@ -237,7 +235,7 @@ - (void)enableNetworkWithCompletion:(nullable FSTVoidErrorBlock)completion {
237235

238236
- (void)shutdownWithCompletion:(nullable FSTVoidErrorBlock)completion {
239237
[self.workerDispatchQueue dispatchAsync:^{
240-
_credentialsProvider->SetUserChangeListener(nullptr);
238+
self->_credentialsProvider->SetUserChangeListener(nullptr);
241239

242240
[self.remoteStore shutdown];
243241
[self.localStore shutdown];

0 commit comments

Comments
 (0)