diff options
author | Ryan Wilson <wilsonryan@google.com> | 2017-08-04 15:42:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-04 15:42:14 -0700 |
commit | 6e00706604c3452ad44fc401e4195e0462da1db1 (patch) | |
tree | 5f660ad33321c862ead8ed2ecb4da5333ca5040f /Firebase/Database | |
parent | 84c21ce80db8251703966e10b12c1b39d9099f12 (diff) |
Move Auth notification constant into Core. (#155)
* Move Auth notification constant into Core.
SDKs that want to listen for the internal Auth notifications needed
to copy the notification strings to their own SDK instead of relying
on Auth's definition in order to avoid a dependency on Auth. By moving
them to Core, SDKs can use the constants without taking on another
dependency.
* Remove Auth stub, add app instance to notification.
Diffstat (limited to 'Firebase/Database')
-rw-r--r-- | Firebase/Database/Api/FIRDatabase.m | 67 | ||||
-rw-r--r-- | Firebase/Database/Login/FAuthTokenProvider.h | 4 | ||||
-rw-r--r-- | Firebase/Database/Login/FAuthTokenProvider.m | 75 | ||||
-rw-r--r-- | Firebase/Database/Public/FIRDatabase.h | 2 |
4 files changed, 33 insertions, 115 deletions
diff --git a/Firebase/Database/Api/FIRDatabase.m b/Firebase/Database/Api/FIRDatabase.m index 7466f4c..38ccd54 100644 --- a/Firebase/Database/Api/FIRDatabase.m +++ b/Firebase/Database/Api/FIRDatabase.m @@ -15,6 +15,7 @@ */ #import <Foundation/Foundation.h> +#import "FIRAppInternal.h" #import "FIRLogger.h" #import "FIRDatabase.h" #import "FIRDatabase_Private.h" @@ -25,25 +26,7 @@ #import "FRepoInfo.h" #import "FIRDatabaseConfig.h" #import "FIRDatabaseReference_Private.h" - -/** - * This is a hack that defines all the methods we need from FIRApp/Options. At runtime we use reflection to get the - * default FIRApp instance if we need it. Since protocols don't carry any runtime information and selectors - * are invoked by name we can write code against this protocol as long as the method signatures don't change. - * - * TODO: Consider weak-linking the actual Firebase/Core framework or something. - */ - -extern NSString *const kFIRDefaultAppName; - -@protocol FIROptionsLike <NSObject> -@property(nonatomic, readonly, copy) NSString *databaseURL; -@end - -@protocol FIRAppLike <NSObject> -@property(nonatomic, readonly) id<FIROptionsLike> options; -@property(nonatomic, copy, readonly) NSString *name; -@end +#import "FIROptions.h" @interface FIRDatabase () @property (nonatomic, strong) FRepoInfo *repoInfo; @@ -77,23 +60,25 @@ static const char *FIREBASE_SEMVER = (const char *)STR(FIRDatabase_VERSION); } + (FIRDatabase *)database { - id<FIRAppLike> app = [FIRDatabase getDefaultApp]; - if (app == nil) { - [NSException raise:@"FIRAppNotConfigured" format:@"Failed to get default FIRDatabase instance. Must call FIRApp.configure() before using FIRDatabase."]; + if (![FIRApp isDefaultAppConfigured]) { + [NSException raise:@"FIRAppNotConfigured" + format:@"Failed to get default Firebase Database instance. Must call `[FIRApp " + @"configure]` (`FirebaseApp.configure()` in Swift) before using " + @"Firebase Database."]; } - return [FIRDatabase databaseForApp:(FIRApp*)app]; + FIRApp *app = [FIRApp defaultApp]; + return [FIRDatabase databaseForApp:app]; } -+ (FIRDatabase *)databaseForApp:(id)app { ++ (FIRDatabase *)databaseForApp:(FIRApp *)app { if (app == nil) { [NSException raise:@"InvalidFIRApp" format:@"nil FIRApp instance passed to databaseForApp."]; } NSMutableDictionary *instances = [self instances]; @synchronized (instances) { - id<FIRAppLike> appLike = (id<FIRAppLike>)app; - FIRDatabase *database = instances[appLike.name]; + FIRDatabase *database = instances[app.name]; if (!database) { - NSString *databaseUrl = appLike.options.databaseURL; + NSString *databaseUrl = app.options.databaseURL; if (databaseUrl == nil) { [NSException raise:@"MissingDatabaseURL" format:@"Failed to get FIRDatabase instance: FIRApp object has no " "databaseURL in its FirebaseOptions object."]; @@ -106,20 +91,20 @@ static const char *FIREBASE_SEMVER = (const char *)STR(FIRDatabase_VERSION); databaseUrl, [parsedUrl.path toString]]; } - id<FAuthTokenProvider> authTokenProvider = [FAuthTokenProvider authTokenProviderForApp:appLike]; + id<FAuthTokenProvider> authTokenProvider = [FAuthTokenProvider authTokenProviderForApp:app]; // If this is the default app, don't set the session persistence key so that we use our // default ("default") instead of the FIRApp default ("[DEFAULT]") so that we // preserve the default location used by the legacy Firebase SDK. NSString *sessionIdentifier = @"default"; - if (![appLike.name isEqualToString:kFIRDefaultAppName]) { - sessionIdentifier = appLike.name; + if ([FIRApp isDefaultAppConfigured] && app == [FIRApp defaultApp]) { + sessionIdentifier = app.name; } FIRDatabaseConfig *config = [[FIRDatabaseConfig alloc] initWithSessionIdentifier:sessionIdentifier authTokenProvider:authTokenProvider]; - database = [[FIRDatabase alloc] initWithApp:appLike repoInfo:parsedUrl.repoInfo config:config]; - instances[appLike.name] = database; + database = [[FIRDatabase alloc] initWithApp:app repoInfo:parsedUrl.repoInfo config:config]; + instances[app.name] = database; } return database; @@ -148,12 +133,12 @@ static const char *FIREBASE_SEMVER = (const char *)STR(FIRDatabase_VERSION); } -- (id)initWithApp:(id <FIRAppLike>)appLike repoInfo:(FRepoInfo *)info config:(FIRDatabaseConfig *)config { +- (id)initWithApp:(FIRApp *)app repoInfo:(FRepoInfo *)info config:(FIRDatabaseConfig *)config { self = [super init]; if (self != nil) { self->_repoInfo = info; self->_config = config; - self->_app = (FIRApp*) appLike; + self->_app = app; } return self; } @@ -204,7 +189,6 @@ static const char *FIREBASE_SEMVER = (const char *)STR(FIRDatabase_VERSION); }); } - - (void)goOffline { [self ensureRepo]; @@ -213,19 +197,6 @@ static const char *FIREBASE_SEMVER = (const char *)STR(FIRDatabase_VERSION); }); } -+ (id<FIRAppLike>) getDefaultApp { - Class appClass = NSClassFromString(@"FIRApp"); - if (appClass == nil) { - [NSException raise:@"FailedToFindFIRApp" format:@"Failed to find FIRApp class."]; - return nil; - } else { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundeclared-selector" - return [appClass performSelector:@selector(defaultApp)]; -#pragma clang diagnostic pop - } -} - - (void)setPersistenceEnabled:(BOOL)persistenceEnabled { [self assertUnfrozen:@"setPersistenceEnabled"]; self->_config.persistenceEnabled = persistenceEnabled; diff --git a/Firebase/Database/Login/FAuthTokenProvider.h b/Firebase/Database/Login/FAuthTokenProvider.h index dca0026..363b82f 100644 --- a/Firebase/Database/Login/FAuthTokenProvider.h +++ b/Firebase/Database/Login/FAuthTokenProvider.h @@ -19,6 +19,8 @@ #import "FTypedefs.h" #import "FTypedefs_Private.h" +@class FIRApp; + @protocol FAuthTokenProvider <NSObject> - (void) fetchTokenForcingRefresh:(BOOL)forceRefresh withCallback:(fbt_void_nsstring_nserror)callback; @@ -29,7 +31,7 @@ @interface FAuthTokenProvider : NSObject -+ (id<FAuthTokenProvider>) authTokenProviderForApp:(id)app; ++ (id<FAuthTokenProvider>) authTokenProviderForApp:(FIRApp *)app; - (instancetype)init NS_UNAVAILABLE; diff --git a/Firebase/Database/Login/FAuthTokenProvider.m b/Firebase/Database/Login/FAuthTokenProvider.m index f3c2a61..8d65609 100644 --- a/Firebase/Database/Login/FAuthTokenProvider.m +++ b/Firebase/Database/Login/FAuthTokenProvider.m @@ -16,65 +16,22 @@ #import "FAuthTokenProvider.h" #import "FUtilities.h" +#import "FIRAppInternal.h" #import "FIRLogger.h" #import "FIRDatabaseQuery_Private.h" #import "FIRNoopAuthTokenProvider.h" -static NSString *const FIRAuthStateDidChangeInternalNotification = @"FIRAuthStateDidChangeInternalNotification"; -static NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey = @"FIRAuthStateDidChangeInternalNotificationTokenKey"; - - -/** - * This is a hack that defines all the methods we need from FIRFirebaseApp. At runtime we use reflection to get an - * actual instance of FIRFirebaseApp. Since protocols don't carry any runtime information and selectors are invoked - * by name we can write code against this protocol as long as the method signatures of FIRFirebaseApp don't change. - */ -@protocol FIRFirebaseAppLike <NSObject> - -- (void)getTokenForcingRefresh:(BOOL)forceRefresh withCallback:(void (^)(NSString *_Nullable token, NSError *_Nullable error))callback; - -@end - - -/** - * This is a hack that defines all the methods we need from FIRAuth. - */ -@protocol FIRFirebaseAuthLike <NSObject> - -- (id<FIRFirebaseAppLike>) app; - -@end - -/** - * This is a hack that copies the definitions of Firebase Auth error codes. If the error codes change in the original code, this - * will break at runtime due to undefined behavior! - */ -typedef NS_ENUM(NSUInteger, FIRErrorCode) { - /*! @var FIRErrorCodeNoAuth - @brief Represents the case where an auth-related message was sent to a @c FIRFirebaseApp - instance which has no associated @c FIRAuth instance. - */ - FIRErrorCodeNoAuth, - - /*! @var FIRErrorCodeNoSignedInUser - @brief Represents the case where an attempt was made to fetch a token when there is no signed - in user. - */ - FIRErrorCodeNoSignedInUser, -}; - - @interface FAuthStateListenerWrapper : NSObject @property (nonatomic, copy) fbt_void_nsstring listener; -@property (nonatomic, weak) id<FIRFirebaseAppLike> app; +@property (nonatomic, weak) FIRApp *app; @end @implementation FAuthStateListenerWrapper -- (instancetype) initWithListener:(fbt_void_nsstring)listener app:(id<FIRFirebaseAppLike>)app { +- (instancetype) initWithListener:(fbt_void_nsstring)listener app:(FIRApp *)app { self = [super init]; if (self != nil) { self->_listener = listener; @@ -88,9 +45,9 @@ typedef NS_ENUM(NSUInteger, FIRErrorCode) { } - (void) authStateDidChangeNotification:(NSNotification *)notification { - id<FIRFirebaseAuthLike> auth = notification.object; - if (auth.app == self->_app) { - NSDictionary *userInfo = notification.userInfo; + NSDictionary *userInfo = notification.userInfo; + FIRApp *authApp = userInfo[FIRAuthStateDidChangeInternalNotificationAppKey]; + if (authApp == self.app) { NSString *token = userInfo[FIRAuthStateDidChangeInternalNotificationTokenKey]; dispatch_async([FIRDatabaseQuery sharedQueue], ^{ self.listener(token); @@ -107,17 +64,17 @@ typedef NS_ENUM(NSUInteger, FIRErrorCode) { @interface FIRFirebaseAuthTokenProvider : NSObject <FAuthTokenProvider> -@property (nonatomic, strong) id<FIRFirebaseAppLike> app; +@property (nonatomic, strong) FIRApp *app; /** Strong references to the auth listeners as they are only weak in FIRFirebaseApp */ @property (nonatomic, strong) NSMutableArray *authListeners; -- (instancetype) initWithFirebaseApp:(id<FIRFirebaseAppLike>)app; +- (instancetype) initWithFirebaseApp:(FIRApp *)app; @end @implementation FIRFirebaseAuthTokenProvider -- (instancetype) initWithFirebaseApp:(id<FIRFirebaseAppLike>)app { +- (instancetype) initWithFirebaseApp:(FIRApp *)app { self = [super init]; if (self != nil) { self->_app = app; @@ -130,19 +87,7 @@ typedef NS_ENUM(NSUInteger, FIRErrorCode) { // TODO: Don't fetch token if there is no current user [self.app getTokenForcingRefresh:forceRefresh withCallback:^(NSString * _Nullable token, NSError * _Nullable error) { dispatch_async([FIRDatabaseQuery sharedQueue], ^{ - if (error != nil) { - if (error.code == FIRErrorCodeNoAuth) { - FFLog(@"I-RDB073001", @"Firebase Auth is not configured, not going to use authentication."); - callback(nil, nil); - } else if (error.code == FIRErrorCodeNoSignedInUser) { - // No signed in user is an expected case, callback as success with no token - callback(nil, nil); - } else { - callback(nil, error); - } - } else { - callback(token, nil); - } + callback(token, error); }); }]; } diff --git a/Firebase/Database/Public/FIRDatabase.h b/Firebase/Database/Public/FIRDatabase.h index fd4535f..a67f96d 100644 --- a/Firebase/Database/Public/FIRDatabase.h +++ b/Firebase/Database/Public/FIRDatabase.h @@ -51,7 +51,7 @@ FIR_SWIFT_NAME(Database) * @param app The FIRApp to get a FIRDatabase for. * @return A FIRDatabase instance. */ -+ (FIRDatabase *) databaseForApp:(FIRApp*)app FIR_SWIFT_NAME(database(app:)); ++ (FIRDatabase *) databaseForApp:(FIRApp *)app FIR_SWIFT_NAME(database(app:)); /** The FIRApp instance to which this FIRDatabase belongs. */ @property (weak, readonly, nonatomic) FIRApp *app; |