Skip to content

Commit 7a4a2ea

Browse files
authored
replacing FSTGetTokenResult by C++ Token implementation (firebase#805)
* replacing Auth/FSTUser by C++ auth implementation * address changes * replacing FSTGetTokenResult by C++ Token implementation * address changes * address changes * fix another const& v.s. dispatch bug * fix more const& v.s. dispatch bug zxu123 committed * fix * passing by value in callback
1 parent a9f3f35 commit 7a4a2ea

15 files changed

+90
-91
lines changed

Firestore/Source/Auth/FSTCredentialsProvider.h

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,53 +16,27 @@
1616

1717
#import <Foundation/Foundation.h>
1818

19+
#include "Firestore/core/src/firebase/firestore/auth/token.h"
1920
#include "Firestore/core/src/firebase/firestore/auth/user.h"
2021

2122
NS_ASSUME_NONNULL_BEGIN
2223

2324
@class FIRApp;
2425
@class FSTDispatchQueue;
2526

26-
#pragma mark - FSTGetTokenResult
27-
28-
/**
29-
* The current User and the authentication token provided by the underlying authentication
30-
* mechanism. This is the result of calling -[FSTCredentialsProvider getTokenForcingRefresh].
31-
*
32-
* ## Portability notes: no TokenType on iOS
33-
*
34-
* The TypeScript client supports 1st party Oauth tokens (for the Firebase Console to auth as the
35-
* developer) and OAuth2 tokens for the node.js sdk to auth with a service account. We don't have
36-
* plans to support either case on mobile so there's no TokenType here.
37-
*/
38-
// TODO(mcg): Rename FSTToken, change parameter order to line up with the other platforms.
39-
@interface FSTGetTokenResult : NSObject
40-
41-
- (instancetype)init NS_UNAVAILABLE;
42-
- (instancetype)initWithUser:(const firebase::firestore::auth::User &)user
43-
token:(NSString *_Nullable)token NS_DESIGNATED_INITIALIZER;
44-
45-
/** The user with which the token is associated (used for persisting user state on disk, etc.). */
46-
@property(nonatomic, assign, readonly) const firebase::firestore::auth::User &user;
47-
48-
/** The actual raw token. */
49-
@property(nonatomic, copy, nullable, readonly) NSString *token;
50-
51-
@end
52-
5327
#pragma mark - Typedefs
5428

5529
/**
5630
* `FSTVoidTokenErrorBlock` is a block that gets a token or an error.
5731
*
58-
* @param token An auth token as a string.
32+
* @param token An auth token, either valid or invalid when error occurred.
5933
* @param error The error if one occurred, or else `nil`.
6034
*/
61-
typedef void (^FSTVoidGetTokenResultBlock)(FSTGetTokenResult *_Nullable token,
35+
typedef void (^FSTVoidGetTokenResultBlock)(firebase::firestore::auth::Token token,
6236
NSError *_Nullable error);
6337

6438
/** Listener block notified with a User. */
65-
typedef void (^FSTVoidUserBlock)(const firebase::firestore::auth::User &user);
39+
typedef void (^FSTVoidUserBlock)(firebase::firestore::auth::User user);
6640

6741
#pragma mark - FSTCredentialsProvider
6842

Firestore/Source/Auth/FSTCredentialsProvider.mm

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,38 +25,16 @@
2525
#import "Firestore/Source/Util/FSTClasses.h"
2626
#import "Firestore/Source/Util/FSTDispatchQueue.h"
2727

28+
#include "Firestore/core/src/firebase/firestore/auth/token.h"
2829
#include "Firestore/core/src/firebase/firestore/auth/user.h"
2930
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
3031

3132
namespace util = firebase::firestore::util;
33+
using firebase::firestore::auth::Token;
3234
using firebase::firestore::auth::User;
3335

3436
NS_ASSUME_NONNULL_BEGIN
3537

36-
#pragma mark - FSTGetTokenResult
37-
38-
@interface FSTGetTokenResult () {
39-
User _user;
40-
}
41-
42-
@end
43-
44-
@implementation FSTGetTokenResult
45-
46-
- (instancetype)initWithUser:(const User &)user token:(NSString *_Nullable)token {
47-
if (self = [super init]) {
48-
_user = user;
49-
_token = token;
50-
}
51-
return self;
52-
}
53-
54-
- (const User &)user {
55-
return _user;
56-
}
57-
58-
@end
59-
6038
#pragma mark - FSTFirebaseCredentialsProvider
6139
@interface FSTFirebaseCredentialsProvider () {
6240
/** The current user as reported to us via our AuthStateDidChangeListener. */
@@ -141,11 +119,9 @@ - (void)getTokenForcingRefresh:(BOOL)forceRefresh
141119
NSError *cancelError = [NSError errorWithDomain:FIRFirestoreErrorDomain
142120
code:FIRFirestoreErrorCodeAborted
143121
userInfo:errorInfo];
144-
completion(nil, cancelError);
122+
completion(Token::Invalid(), cancelError);
145123
} else {
146-
FSTGetTokenResult *result =
147-
[[FSTGetTokenResult alloc] initWithUser:_currentUser token:token];
148-
completion(result, error);
124+
completion(Token(util::MakeStringView(token), _currentUser), error);
149125
}
150126
};
151127
};

Firestore/Source/Auth/FSTEmptyCredentialsProvider.mm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
#import "Firestore/Source/Util/FSTAssert.h"
2020
#import "Firestore/Source/Util/FSTDispatchQueue.h"
2121

22+
#include "Firestore/core/src/firebase/firestore/auth/token.h"
2223
#include "Firestore/core/src/firebase/firestore/auth/user.h"
2324

25+
using firebase::firestore::auth::Token;
2426
using firebase::firestore::auth::User;
2527

2628
NS_ASSUME_NONNULL_BEGIN
@@ -29,7 +31,8 @@ @implementation FSTEmptyCredentialsProvider
2931

3032
- (void)getTokenForcingRefresh:(BOOL)forceRefresh
3133
completion:(FSTVoidGetTokenResultBlock)completion {
32-
completion(nil, nil);
34+
// Invalid token will force the GRPC fallback to use default settings.
35+
completion(Token::Invalid(), nil);
3336
}
3437

3538
- (void)setUserChangeListener:(nullable FSTVoidUserBlock)block {

Firestore/Source/Core/FSTFirestoreClient.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ - (instancetype)initWithDatabaseInfo:(const DatabaseInfo &)databaseInfo
103103
__block bool initialized = false;
104104
__block User initialUser;
105105
FSTWeakify(self);
106-
_credentialsProvider.userChangeListener = ^(const User &user) {
106+
_credentialsProvider.userChangeListener = ^(User user) {
107107
FSTStrongify(self);
108108
if (self) {
109109
if (!initialized) {

Firestore/Source/Remote/FSTDatastore.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "Firestore/core/src/firebase/firestore/core/database_info.h"
2222
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
23+
#include "absl/strings/string_view.h"
2324

2425
@class FSTDocumentKey;
2526
@class FSTDispatchQueue;
@@ -83,7 +84,7 @@ NS_ASSUME_NONNULL_BEGIN
8384
/** Adds headers to the RPC including any OAuth access token if provided .*/
8485
+ (void)prepareHeadersForRPC:(GRPCCall *)rpc
8586
databaseID:(const firebase::firestore::model::DatabaseId *)databaseID
86-
token:(nullable NSString *)token;
87+
token:(const absl::string_view)token;
8788

8889
/** Looks up a list of documents in datastore. */
8990
- (void)lookupDocuments:(NSArray<FSTDocumentKey *> *)keys

Firestore/Source/Remote/FSTDatastore.mm

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@
3535

3636
#import "Firestore/Protos/objc/google/firestore/v1beta1/Firestore.pbrpc.h"
3737

38+
#include "Firestore/core/src/firebase/firestore/auth/token.h"
3839
#include "Firestore/core/src/firebase/firestore/core/database_info.h"
3940
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
4041
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
4142

4243
namespace util = firebase::firestore::util;
44+
using firebase::firestore::auth::Token;
4345
using firebase::firestore::core::DatabaseInfo;
4446
using firebase::firestore::model::DatabaseId;
4547

@@ -301,16 +303,18 @@ - (void)invokeRPCWithFactory:(GRPCProtoCall * (^)(void))rpcFactory
301303
// but I'm not sure how to detect that right now. http://b/32762461
302304
[self.credentials
303305
getTokenForcingRefresh:NO
304-
completion:^(FSTGetTokenResult *_Nullable result, NSError *_Nullable error) {
306+
completion:^(Token result, NSError *_Nullable error) {
305307
error = [FSTDatastore firestoreErrorForError:error];
306308
[self.workerDispatchQueue dispatchAsyncAllowingSameQueue:^{
307309
if (error) {
308310
errorHandler(error);
309311
} else {
310312
GRPCProtoCall *rpc = rpcFactory();
311-
[FSTDatastore prepareHeadersForRPC:rpc
312-
databaseID:&self.databaseInfo->database_id()
313-
token:result.token];
313+
[FSTDatastore
314+
prepareHeadersForRPC:rpc
315+
databaseID:&self.databaseInfo->database_id()
316+
token:(result.is_valid() ? result.token()
317+
: absl::string_view())];
314318
[rpc start];
315319
}
316320
}];
@@ -334,8 +338,8 @@ - (FSTWriteStream *)createWriteStream {
334338
/** Adds headers to the RPC including any OAuth access token if provided .*/
335339
+ (void)prepareHeadersForRPC:(GRPCCall *)rpc
336340
databaseID:(const DatabaseId *)databaseID
337-
token:(nullable NSString *)token {
338-
rpc.oauth2AccessToken = token;
341+
token:(const absl::string_view)token {
342+
rpc.oauth2AccessToken = token.data() == nullptr ? nil : util::WrapNSString(token);
339343
rpc.requestHeaders[kXGoogAPIClientHeader] = [FSTDatastore googAPIClientHeaderValue];
340344
// This header is used to improve routing and project isolation by the backend.
341345
rpc.requestHeaders[kGoogleCloudResourcePrefix] =

Firestore/Source/Remote/FSTStream.mm

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@
3535

3636
#import "Firestore/Protos/objc/google/firestore/v1beta1/Firestore.pbrpc.h"
3737

38+
#include "Firestore/core/src/firebase/firestore/auth/token.h"
3839
#include "Firestore/core/src/firebase/firestore/core/database_info.h"
3940
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
4041
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
4142

4243
namespace util = firebase::firestore::util;
44+
using firebase::firestore::auth::Token;
4345
using firebase::firestore::core::DatabaseInfo;
4446
using firebase::firestore::model::DatabaseId;
4547

@@ -256,18 +258,17 @@ - (void)startWithDelegate:(id)delegate {
256258
FSTAssert(_delegate == nil, @"Delegate must be nil");
257259
_delegate = delegate;
258260

259-
[self.credentials
260-
getTokenForcingRefresh:NO
261-
completion:^(FSTGetTokenResult *_Nullable result, NSError *_Nullable error) {
262-
error = [FSTDatastore firestoreErrorForError:error];
263-
[self.workerDispatchQueue dispatchAsyncAllowingSameQueue:^{
264-
[self resumeStartWithToken:result error:error];
265-
}];
266-
}];
261+
[self.credentials getTokenForcingRefresh:NO
262+
completion:^(Token result, NSError *_Nullable error) {
263+
error = [FSTDatastore firestoreErrorForError:error];
264+
[self.workerDispatchQueue dispatchAsyncAllowingSameQueue:^{
265+
[self resumeStartWithToken:result error:error];
266+
}];
267+
}];
267268
}
268269

269270
/** Add an access token to our RPC, after obtaining one from the credentials provider. */
270-
- (void)resumeStartWithToken:(FSTGetTokenResult *)token error:(NSError *)error {
271+
- (void)resumeStartWithToken:(const Token &)token error:(NSError *)error {
271272
if (self.state == FSTStreamStateStopped) {
272273
// Streams can be stopped while waiting for authorization.
273274
return;
@@ -289,7 +290,7 @@ - (void)resumeStartWithToken:(FSTGetTokenResult *)token error:(NSError *)error {
289290
_rpc = [self createRPCWithRequestsWriter:self.requestsWriter];
290291
[FSTDatastore prepareHeadersForRPC:_rpc
291292
databaseID:&self.databaseInfo->database_id()
292-
token:token.token];
293+
token:(token.is_valid() ? token.token() : absl::string_view())];
293294
FSTAssert(_callbackFilter == nil, @"GRX Filter must be nil");
294295
_callbackFilter = [[FSTCallbackFilter alloc] initWithStream:self];
295296
[_rpc startWithWriteable:_callbackFilter];

Firestore/core/src/firebase/firestore/auth/credentials_provider.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ namespace auth {
3131
// `TokenErrorListener` is a listener that gets a token or an error.
3232
// token: An auth token as a string, or nullptr if error occurred.
3333
// error: The error if one occurred, or else nullptr.
34-
typedef std::function<void(const Token& token, const absl::string_view error)>
34+
typedef std::function<void(Token token, const absl::string_view error)>
3535
TokenListener;
3636

3737
// Listener notified with a User change.
38-
typedef std::function<void(const User& user)> UserChangeListener;
38+
typedef std::function<void(User user)> UserChangeListener;
3939

4040
/**
4141
* Provides methods for getting the uid and token for the current user and

Firestore/core/src/firebase/firestore/auth/token.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,15 @@ namespace firestore {
2121
namespace auth {
2222

2323
Token::Token(const absl::string_view token, const User& user)
24-
: token_(token), user_(user) {
24+
: token_(token), user_(user), is_valid_(true) {
25+
}
26+
27+
Token::Token() : token_(), user_(User::Unauthenticated()), is_valid_(false) {
28+
}
29+
30+
const Token& Token::Invalid() {
31+
static const Token kInvalidToken;
32+
return kInvalidToken;
2533
}
2634

2735
} // namespace auth

Firestore/core/src/firebase/firestore/auth/token.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <string>
2121

2222
#include "Firestore/core/src/firebase/firestore/auth/user.h"
23+
#include "Firestore/core/src/firebase/firestore/util/firebase_assert.h"
2324
#include "absl/strings/string_view.h"
2425

2526
namespace firebase {
@@ -45,6 +46,7 @@ class Token {
4546

4647
/** The actual raw token. */
4748
const std::string& token() const {
49+
FIREBASE_ASSERT(is_valid_);
4850
return token_;
4951
}
5052

@@ -56,9 +58,26 @@ class Token {
5658
return user_;
5759
}
5860

61+
/**
62+
* Whether the token is a valid one.
63+
*
64+
* ## Portability notes: Invalid token is the equivalent of nil in the iOS
65+
* token implementation. We use value instead of pointer for Token instance in
66+
* the C++ migration.
67+
*/
68+
bool is_valid() const {
69+
return is_valid_;
70+
}
71+
72+
/** Returns an invalid token. */
73+
static const Token& Invalid();
74+
5975
private:
76+
Token();
77+
6078
const std::string token_;
6179
const User user_;
80+
const bool is_valid_;
6281
};
6382

6483
} // namespace auth

0 commit comments

Comments
 (0)