2017-03-09 15:26:28 +00:00
|
|
|
#import "RNFirebase.h"
|
|
|
|
#import "RNFirebaseErrors.h"
|
|
|
|
#import "RNFirebaseEvents.h"
|
|
|
|
|
|
|
|
static RNFirebase *_sharedInstance = nil;
|
|
|
|
static dispatch_once_t onceToken;
|
|
|
|
|
|
|
|
@implementation RNFirebase
|
|
|
|
|
|
|
|
typedef void (^UserWithTokenResponse)(NSDictionary *, NSError *);
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
|
|
|
NSLog(@"Dealloc called on RNFirebase: %@", self);
|
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Implement
|
|
|
|
+ (void) setup:(UIApplication *) application
|
|
|
|
withLaunchOptions: (NSDictionary *) launchOptions
|
|
|
|
{
|
|
|
|
NSLog(@"Called setup for RNFirebase");
|
|
|
|
|
|
|
|
dispatch_once(&onceToken, ^{
|
|
|
|
[application registerForRemoteNotifications];
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter]
|
|
|
|
postNotificationName:kRNFirebaseInitialized
|
|
|
|
object:nil];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
self = [super init];
|
|
|
|
if (self != nil) {
|
|
|
|
NSLog(@"Setting up RNFirebase instance");
|
|
|
|
[RNFirebase initializeRNFirebase:self];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (void) initializeRNFirebase:(RNFirebase *) instance
|
|
|
|
{
|
|
|
|
dispatch_once(&onceToken, ^{
|
|
|
|
_sharedInstance = instance;
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter]
|
|
|
|
postNotificationName:kRNFirebaseInitialized
|
|
|
|
object:nil];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+ (instancetype) sharedInstance
|
|
|
|
{
|
|
|
|
return _sharedInstance;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (FIRApp *) firebaseApp
|
|
|
|
{
|
|
|
|
return [FIRApp defaultApp];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RCT_EXPORT_MODULE(RNFirebase);
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(serverValue:(RCTResponseSenderBlock) callback)
|
|
|
|
{
|
|
|
|
callback(@[[NSNull null], @{
|
|
|
|
@"TIMESTAMP": [FIRServerValue timestamp]
|
|
|
|
}]);
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(configureWithOptions:(NSDictionary *) opts
|
|
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
|
|
|
dispatch_async(dispatch_get_main_queue(),^{
|
|
|
|
// Are we debugging, yo?
|
|
|
|
self.debug = [opts valueForKey:@"debug"] != nil ? YES : NO;
|
|
|
|
NSLog(@"options passed into configureWithOptions: %@", [opts valueForKey:@"debug"]);
|
|
|
|
|
|
|
|
NSDictionary *keyMapping = @{
|
|
|
|
@"GOOGLE_APP_ID": @[
|
|
|
|
@"appId",
|
|
|
|
@"googleAppId",
|
|
|
|
@"applicationId"
|
|
|
|
],
|
|
|
|
@"BUNDLE_ID": @[
|
|
|
|
@"bundleId",
|
|
|
|
@"bundleID"
|
|
|
|
],
|
|
|
|
@"GCM_SENDER_ID": @[
|
|
|
|
@"gcmSenderID",
|
|
|
|
@"GCMSenderID"
|
|
|
|
],
|
|
|
|
@"API_KEY": @[
|
|
|
|
@"apiKey"
|
|
|
|
],
|
|
|
|
@"CLIENT_ID": @[
|
|
|
|
@"clientId",
|
|
|
|
@"clientID"
|
|
|
|
],
|
|
|
|
@"TRACKING_ID": @[
|
|
|
|
@"trackingID",
|
|
|
|
@"trackingId"
|
|
|
|
],
|
|
|
|
@"ANDROID_CLIENT_ID": @[
|
|
|
|
@"applicationId",
|
|
|
|
@"clientId",
|
|
|
|
@"clientID",
|
|
|
|
@"androidClientID",
|
|
|
|
@"androidClientId"
|
|
|
|
],
|
|
|
|
@"DATABASE_URL": @[
|
|
|
|
@"databaseUrl",
|
|
|
|
@"databaseURL"
|
|
|
|
],
|
|
|
|
@"STORAGE_BUCKET": @[
|
|
|
|
@"storageBucket"
|
|
|
|
],
|
|
|
|
@"PROJECT_ID": @[
|
|
|
|
@"projectId",
|
|
|
|
@"projectID"
|
|
|
|
],
|
|
|
|
@"TRACKING_ID": @[
|
|
|
|
@"trackingID",
|
|
|
|
@"trackingId"
|
|
|
|
],
|
|
|
|
@"DEEP_LINK_SCHEME": @[
|
|
|
|
@"deepLinkScheme"
|
|
|
|
],
|
|
|
|
@"MESSAGING_SENDER_ID": @[
|
|
|
|
@"messagingSenderId",
|
|
|
|
@"messagingSenderID"
|
|
|
|
]
|
|
|
|
};
|
|
|
|
NSArray *optionKeys = [keyMapping allKeys];
|
|
|
|
|
|
|
|
NSMutableDictionary *props;
|
|
|
|
|
|
|
|
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"];
|
|
|
|
|
|
|
|
if ([[NSFileManager defaultManager] fileExistsAtPath:plistPath]) {
|
|
|
|
// If the Firebase plist is included
|
|
|
|
props = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
|
|
|
|
} else {
|
|
|
|
props = [[NSMutableDictionary alloc] initWithCapacity:[optionKeys count]];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bundle ID either from options OR from the main bundle
|
|
|
|
NSString *bundleID;
|
|
|
|
if ([opts valueForKey:@"bundleID"]) {
|
|
|
|
bundleID = [opts valueForKey:@"bundleID"];
|
|
|
|
} else {
|
|
|
|
bundleID = [[NSBundle mainBundle] bundleIdentifier];
|
|
|
|
}
|
|
|
|
[props setValue:bundleID forKey:@"BUNDLE_ID"];
|
|
|
|
|
|
|
|
// Prefer the user configuration options over the default options
|
|
|
|
for (int i=0; i < [optionKeys count]; i++) {
|
|
|
|
// Traditional for loop here
|
|
|
|
@try {
|
|
|
|
NSString *key = [optionKeys objectAtIndex:i];
|
|
|
|
// If the name is capitalized
|
|
|
|
if ([opts valueForKey:key] != nil) {
|
|
|
|
NSString *value = [opts valueForKey:key];
|
|
|
|
[props setValue:value forKey:key];
|
|
|
|
}
|
|
|
|
|
|
|
|
NSArray *possibleNames = [keyMapping objectForKey:key];
|
|
|
|
|
|
|
|
for (NSString *name in possibleNames) {
|
|
|
|
if ([opts valueForKey:name] != nil) {
|
|
|
|
// The user passed this option in
|
|
|
|
NSString *value = [opts valueForKey:name];
|
|
|
|
[props setValue:value forKey:key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@catch (NSException *err) {
|
|
|
|
// Uh oh?
|
|
|
|
NSLog(@"An error occurred: %@", err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@try {
|
|
|
|
if (self.debug) {
|
|
|
|
NSLog(@"props ->: %@", props);
|
|
|
|
NSLog(@"GOOGLE_APP_ID: %@", [props valueForKey:@"GOOGLE_APP_ID"]);
|
|
|
|
NSLog(@"BUNDLE_ID: %@", [props valueForKey:@"BUNDLE_ID"]);
|
|
|
|
NSLog(@"GCM_SENDER_ID: %@", [props valueForKey:@"GCM_SENDER_ID"]);
|
|
|
|
NSLog(@"API_KEY: %@", [props valueForKey:@"API_KEY"]);
|
|
|
|
NSLog(@"CLIENT_ID: %@", [props valueForKey:@"CLIENT_ID"]);
|
|
|
|
NSLog(@"TRACKING_ID: %@", [props valueForKey:@"TRACKING_ID"]);
|
|
|
|
NSLog(@"ANDROID_CLIENT_ID: %@", [props valueForKey:@"ANDROID_CLIENT_ID"]);
|
|
|
|
NSLog(@"DATABASE_URL: %@", [props valueForKey:@"DATABASE_URL"]);
|
|
|
|
NSLog(@"STORAGE_BUCKET: %@", [props valueForKey:@"STORAGE_BUCKET"]);
|
|
|
|
NSLog(@"DEEP_LINK_SCHEME: %@", [props valueForKey:@"DEEP_LINK_SCHEME"]);
|
|
|
|
}
|
|
|
|
|
|
|
|
FIROptions *finalOptions = [[FIROptions alloc]
|
|
|
|
initWithGoogleAppID:[props valueForKey:@"GOOGLE_APP_ID"]
|
|
|
|
bundleID:[props valueForKey:@"BUNDLE_ID"]
|
|
|
|
GCMSenderID:[props valueForKey:@"GCM_SENDER_ID"]
|
|
|
|
APIKey:[props valueForKey:@"API_KEY"]
|
|
|
|
clientID:[props valueForKey:@"CLIENT_ID"]
|
|
|
|
trackingID:[props valueForKey:@"TRACKING_ID"]
|
|
|
|
androidClientID:[props valueForKey:@"ANDROID_CLIENT_ID"]
|
|
|
|
databaseURL:[props valueForKey:@"DATABASE_URL"]
|
|
|
|
storageBucket:[props valueForKey:@"STORAGE_BUCKET"]
|
|
|
|
deepLinkURLScheme:[props valueForKey:@"DEEP_LINK_SCHEME"]];
|
|
|
|
|
|
|
|
// Save configuration option
|
|
|
|
// NSDictionary *cfg = [self getConfig];
|
|
|
|
// [cfg setValuesForKeysWithDictionary:props];
|
|
|
|
|
|
|
|
// if (!self.configured) {
|
|
|
|
|
|
|
|
if ([FIRApp defaultApp] == NULL) {
|
|
|
|
[FIRApp configureWithOptions:finalOptions];
|
|
|
|
}
|
|
|
|
[RNFirebase initializeRNFirebase:self];
|
|
|
|
callback(@[[NSNull null], props]);
|
|
|
|
}
|
|
|
|
@catch (NSException *exception) {
|
|
|
|
NSLog(@"Exception occurred while configuring: %@", exception);
|
|
|
|
[self debugLog:@"Configuring error"
|
|
|
|
msg:[NSString stringWithFormat:@"An error occurred while configuring: %@", [exception debugDescription]]];
|
|
|
|
NSDictionary *errProps = @{
|
|
|
|
@"error": [exception name],
|
|
|
|
@"description": [exception debugDescription]
|
|
|
|
};
|
|
|
|
callback(@[errProps]);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(configure:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
|
|
|
NSDictionary *props = @{};
|
|
|
|
[self configureWithOptions:props
|
|
|
|
callback:callback];
|
|
|
|
}
|
|
|
|
|
2017-05-19 07:49:49 +00:00
|
|
|
#pragma mark Storage
|
2017-03-09 15:26:28 +00:00
|
|
|
|
|
|
|
#pragma mark RemoteConfig
|
|
|
|
|
|
|
|
#pragma mark Database
|
|
|
|
|
|
|
|
#pragma mark Messaging
|
|
|
|
|
|
|
|
#pragma mark Helpers
|
|
|
|
|
|
|
|
- (NSDictionary *) getConfig
|
|
|
|
{
|
|
|
|
if (self.configuration == nil) {
|
|
|
|
self.configuration = [[NSMutableDictionary alloc] initWithCapacity:20];
|
|
|
|
}
|
|
|
|
return self.configuration;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSDictionary *) handleFirebaseError:(NSString *) name
|
|
|
|
error:(NSError *) error
|
|
|
|
withUser:(FIRUser *) user
|
|
|
|
{
|
|
|
|
return [RNFirebaseErrors handleFirebaseError:name
|
|
|
|
error:error
|
|
|
|
withUser:user];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) handleException:(NSException *)exception
|
|
|
|
withCallback:(RCTResponseSenderBlock)callback
|
|
|
|
{
|
|
|
|
[RNFirebaseErrors handleException:exception
|
|
|
|
withCallback:callback];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) debugLog:(NSString *)title
|
|
|
|
msg:(NSString *)msg
|
|
|
|
{
|
|
|
|
if (self.debug) {
|
|
|
|
NSLog(@"%@: %@", title, msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Not sure how to get away from this... yet
|
|
|
|
- (NSArray<NSString *> *)supportedEvents {
|
|
|
|
return @[
|
|
|
|
INITIALIZED_EVENT,
|
|
|
|
DEBUG_EVENT,
|
|
|
|
AUTH_CHANGED_EVENT];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) sendJSEvent:(NSString *)title
|
|
|
|
props:(NSDictionary *)props
|
|
|
|
{
|
|
|
|
@try {
|
|
|
|
[self sendEventWithName:title
|
|
|
|
body:props];
|
|
|
|
}
|
|
|
|
@catch (NSException *err) {
|
|
|
|
NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|