Merge branch 'perf-mon' of github.com:invertase/react-native-firebase into perf-mon
This commit is contained in:
commit
8df8f5a68c
@ -128,13 +128,13 @@ firebase.config().setDefaults({
|
||||
hasExperimentalFeature: false,
|
||||
});
|
||||
|
||||
firebase.remoteConfig.fetch()
|
||||
firebase.config().fetch()
|
||||
.then(() => {
|
||||
return firebase.remoteConfig().activateFetched();
|
||||
return firebase.config().activateFetched();
|
||||
})
|
||||
.then((activated) => {
|
||||
if (!activated) console.log('Fetched data not activated');
|
||||
return firebase.remoteConfig().getValue('hasExperimentalFeature');
|
||||
return firebase.config().getValue('hasExperimentalFeature');
|
||||
})
|
||||
.then((snapshot) => {
|
||||
const hasExperimentalFeature = snapshot.val();
|
||||
|
@ -21,23 +21,6 @@
|
||||
@interface RNFirebase : RCTEventEmitter <RCTBridgeModule> {
|
||||
}
|
||||
|
||||
// + (void) registerForNotification:(NSString *) typeStr andToken:(NSData *)deviceToken;
|
||||
+ (void) setup:(UIApplication *) application
|
||||
withLaunchOptions: (NSDictionary *) launchOptions;
|
||||
|
||||
+ (id) sharedInstance;
|
||||
|
||||
- (void) debugLog:(NSString *)title
|
||||
msg:(NSString *)msg;
|
||||
|
||||
- (void) sendJSEvent:(NSString *)title
|
||||
props:(NSDictionary *)props;
|
||||
|
||||
|
||||
@property (nonatomic) BOOL debug;
|
||||
@property (atomic) BOOL configured;
|
||||
@property (nonatomic, strong) NSDictionary *configuration;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
@ -1,308 +1,34 @@
|
||||
#import "RNFirebase.h"
|
||||
#import "RNFirebaseErrors.h"
|
||||
#import "RNFirebaseEvents.h"
|
||||
|
||||
static RNFirebase *_sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
|
||||
@implementation RNFirebase
|
||||
RCT_EXPORT_MODULE(RNFirebase);
|
||||
|
||||
typedef void (^UserWithTokenResponse)(NSDictionary *, NSError *);
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
- (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
|
||||
{
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
NSLog(@"Setting up RNFirebase instance");
|
||||
[RNFirebase initializeRNFirebase:self];
|
||||
[RNFirebase initializeRNFirebase];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void) initializeRNFirebase:(RNFirebase *) instance
|
||||
{
|
||||
+ (void)initializeRNFirebase {
|
||||
dispatch_once(&onceToken, ^{
|
||||
_sharedInstance = instance;
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName:kRNFirebaseInitialized
|
||||
object:nil];
|
||||
[[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];
|
||||
}
|
||||
|
||||
#pragma mark Storage
|
||||
|
||||
#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];
|
||||
return @[INITIALIZED_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
|
||||
@end
|
@ -1,58 +1,41 @@
|
||||
#import "RNFirebase.h"
|
||||
#import "RNFirebaseEvents.h"
|
||||
#import "RNFirebaseAnalytics.h"
|
||||
#import "Firebase.h"
|
||||
|
||||
#if __has_include(<FirebaseAnalytics/FIRAnalytics.h>)
|
||||
#import <FirebaseAnalytics/FIRAnalytics.h>
|
||||
#import <FirebaseAnalytics/FIRAnalyticsConfiguration.h>
|
||||
|
||||
@implementation RNFirebaseAnalytics
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE(RNFirebaseAnalytics);
|
||||
|
||||
// Implementation
|
||||
RCT_EXPORT_METHOD(logEvent:(NSString *)name
|
||||
props:(NSDictionary *)props)
|
||||
{
|
||||
NSString *debugMsg = [NSString stringWithFormat:@"%@: %@ with %@",
|
||||
@"RNFirebaseAnalytics", name, props];
|
||||
[[RNFirebase sharedInstance] debugLog:@"logEventWithName called"
|
||||
msg:debugMsg];
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
RCT_EXPORT_METHOD(logEvent:(NSString *)name props:(NSDictionary *)props) {
|
||||
[FIRAnalytics logEventWithName:name parameters:props];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setAnalyticsCollectionEnabled:(BOOL) enabled)
|
||||
{
|
||||
RCT_EXPORT_METHOD(setAnalyticsCollectionEnabled:(BOOL) enabled) {
|
||||
[[FIRAnalyticsConfiguration sharedInstance] setAnalyticsCollectionEnabled:enabled];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setCurrentScreen:(NSString *) screenName
|
||||
screenClass:(NSString *) screenClassOverriew)
|
||||
{
|
||||
RCT_EXPORT_METHOD(setCurrentScreen:(NSString *) screenName screenClass:(NSString *) screenClassOverriew) {
|
||||
[FIRAnalytics setScreenName:screenName screenClass:screenClassOverriew];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setMinimumSessionDuration:(nonnull NSNumber *) milliseconds)
|
||||
{
|
||||
//Not implemented on iOS
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setSessionTimeoutDuration:(nonnull NSNumber *) milliseconds)
|
||||
{
|
||||
//Not implemented on iOS
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setUserId: (NSString *) id)
|
||||
{
|
||||
RCT_EXPORT_METHOD(setUserId: (NSString *) id) {
|
||||
[FIRAnalytics setUserID:id];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setUserProperty: (NSString *) name
|
||||
value:(NSString *) value)
|
||||
{
|
||||
RCT_EXPORT_METHOD(setUserProperty: (NSString *) name value:(NSString *) value) {
|
||||
[FIRAnalytics setUserPropertyString:value forName:name];
|
||||
}
|
||||
|
||||
// not implemented on iOS sdk
|
||||
RCT_EXPORT_METHOD(setMinimumSessionDuration:(nonnull NSNumber *) milliseconds) {}
|
||||
RCT_EXPORT_METHOD(setSessionTimeoutDuration:(nonnull NSNumber *) milliseconds) {}
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation RNFirebaseAnalytics
|
||||
RCT_EXPORT_MODULE();
|
||||
RCT_EXPORT_METHOD(nativeSDKMissing) {}
|
||||
@end
|
||||
#endif
|
||||
|
@ -1,5 +1,4 @@
|
||||
#import "RNFirebaseAuth.h"
|
||||
#import "RNFirebaseErrors.h"
|
||||
#import "RNFirebaseEvents.h"
|
||||
|
||||
@implementation RNFirebaseAuth
|
||||
|
@ -1,26 +1,29 @@
|
||||
#import "RNFirebaseCrash.h"
|
||||
#import "Firebase.h"
|
||||
|
||||
#if __has_include(<FirebaseCrash/FIRCrashLog.h>)
|
||||
#import "FirebaseCrash/FIRCrashLog.h"
|
||||
|
||||
@implementation RNFirebaseCrash
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
RCT_EXPORT_MODULE(RNFirebaseCrash);
|
||||
|
||||
RCT_EXPORT_METHOD(log:(NSString *)message)
|
||||
{
|
||||
RCT_EXPORT_METHOD(log:(NSString *)message) {
|
||||
FIRCrashLog(message);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(logcat:(nonnull NSNumber *) level
|
||||
tag:(NSString *) tag
|
||||
message:(NSString *) message)
|
||||
{
|
||||
RCT_EXPORT_METHOD(logcat:(nonnull NSNumber *) level tag:(NSString *) tag message:(NSString *) message) {
|
||||
FIRCrashLog(message);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(report:(NSString *) message)
|
||||
{
|
||||
RCT_EXPORT_METHOD(report:(NSString *) message) {
|
||||
FIRCrashLog(message);
|
||||
assert(NO);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation RNFirebaseCrash
|
||||
RCT_EXPORT_MODULE();
|
||||
RCT_EXPORT_METHOD(nativeSDKMissing) {}
|
||||
@end
|
||||
#endif
|
@ -1,6 +1,7 @@
|
||||
#import "RNFirebasePerformance.h"
|
||||
#import "FirebasePerformance/FIRPerformance.h"
|
||||
|
||||
#if __has_include(<FirebasePerformance/FIRPerformance.h>)
|
||||
#import <FirebasePerformance/FIRPerformance.h>
|
||||
@implementation RNFirebasePerformance
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
@ -45,3 +46,10 @@ RCT_EXPORT_METHOD(incrementCounter:
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation RNFirebasePerformance
|
||||
RCT_EXPORT_MODULE();
|
||||
RCT_EXPORT_METHOD(nativeSDKMissing) {}
|
||||
@end
|
||||
#endif
|
||||
|
@ -5,12 +5,9 @@
|
||||
#else // Compatibility for RN version < 0.40
|
||||
#import "RCTConvert.h"
|
||||
#endif
|
||||
#if __has_include(<React/RCTUtils.h>)
|
||||
#import <React/RCTUtils.h>
|
||||
#else // Compatibility for RN version < 0.40
|
||||
#import "RCTUtils.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if __has_include(<FirebaseRemoteConfig/FirebaseRemoteConfig.h>)
|
||||
#import "FirebaseRemoteConfig/FirebaseRemoteConfig.h"
|
||||
|
||||
NSString *convertFIRRemoteConfigFetchStatusToNSString(FIRRemoteConfigFetchStatus value)
|
||||
@ -68,15 +65,12 @@ RCT_EXPORT_MODULE(RNFirebaseRemoteConfig);
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(enableDeveloperMode)
|
||||
{
|
||||
RCT_EXPORT_METHOD(enableDeveloperMode) {
|
||||
FIRRemoteConfigSettings *remoteConfigSettings = [[FIRRemoteConfigSettings alloc] initWithDeveloperModeEnabled:YES];
|
||||
self.remoteConfig.configSettings = remoteConfigSettings;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(fetch:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
RCT_EXPORT_METHOD(fetch:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[self.remoteConfig fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *__nullable error) {
|
||||
if (error) {
|
||||
RCTLogError(@"\nError: %@", RCTJSErrorFromNSError(error));
|
||||
@ -140,14 +134,19 @@ RCT_EXPORT_METHOD(getKeysByPrefix:(NSString *)prefix
|
||||
resolve(keysArray);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setDefaults:(NSDictionary *)defaults)
|
||||
{
|
||||
RCT_EXPORT_METHOD(setDefaults:(NSDictionary *)defaults) {
|
||||
[self.remoteConfig setDefaults:defaults];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setDefaultsFromResource:(NSString *)fileName)
|
||||
{
|
||||
RCT_EXPORT_METHOD(setDefaultsFromResource:(NSString *)fileName) {
|
||||
[self.remoteConfig setDefaultsFromPlistFileName:fileName];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation RNFirebaseRemoteConfig
|
||||
RCT_EXPORT_MODULE();
|
||||
RCT_EXPORT_METHOD(nativeSDKMissing) {}
|
||||
@end
|
||||
#endif
|
@ -1,7 +1,6 @@
|
||||
#ifndef RNFirebaseStorage_h
|
||||
#define RNFirebaseStorage_h
|
||||
|
||||
#import "Firebase.h"
|
||||
#if __has_include(<React/RCTEventEmitter.h>)
|
||||
#import <React/RCTEventEmitter.h>
|
||||
#else // Compatibility for RN version < 0.40
|
||||
@ -17,8 +16,6 @@
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic) NSString *_storageUrl;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,9 @@
|
||||
#import "RNFirebaseStorage.h"
|
||||
#import "RNFirebaseEvents.h"
|
||||
|
||||
#if __has_include(<FirebaseStorage/FIRStorage.h>)
|
||||
#import "RNFirebaseEvents.h"
|
||||
#import <Photos/Photos.h>
|
||||
#import "Firebase.h"
|
||||
|
||||
@implementation RNFirebaseStorage
|
||||
|
||||
@ -21,11 +23,11 @@ RCT_EXPORT_MODULE(RNFirebaseStorage);
|
||||
- (void) promiseRejectStorageException:(RCTPromiseRejectBlock) reject error:(NSError *)error {
|
||||
NSString *code = @"storage/unknown";
|
||||
NSString *message = [error localizedDescription];
|
||||
|
||||
|
||||
NSDictionary *userInfo = [error userInfo];
|
||||
NSError *underlyingError = [userInfo objectForKey:NSUnderlyingErrorKey];
|
||||
NSError *underlyingError = userInfo[NSUnderlyingErrorKey];
|
||||
NSString *underlyingErrorDescription = [underlyingError localizedDescription];
|
||||
|
||||
|
||||
switch (error.code) {
|
||||
case FIRStorageErrorCodeUnknown:
|
||||
if ([underlyingErrorDescription isEqualToString:@"The operation couldn’t be completed. Permission denied"]) {
|
||||
@ -79,8 +81,8 @@ RCT_EXPORT_MODULE(RNFirebaseStorage);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (userInfo != nil && [userInfo objectForKey:@"data"]) {
|
||||
|
||||
if (userInfo != nil && userInfo[@"data"]) {
|
||||
// errors with 'data' are unserializable - it breaks react so we send nil instead
|
||||
reject(code, message, nil);
|
||||
} else {
|
||||
@ -97,7 +99,7 @@ RCT_EXPORT_MODULE(RNFirebaseStorage);
|
||||
*/
|
||||
RCT_EXPORT_METHOD(delete: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
FIRStorageReference *fileRef = [self getReference:path];
|
||||
|
||||
|
||||
[fileRef deleteWithCompletion:^(NSError * _Nullable error) {
|
||||
if (error != nil) {
|
||||
[self promiseRejectStorageException:reject error: error];
|
||||
@ -115,7 +117,7 @@ RCT_EXPORT_METHOD(delete: (NSString *) path resolver:(RCTPromiseResolveBlock)res
|
||||
*/
|
||||
RCT_EXPORT_METHOD(getDownloadURL: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
FIRStorageReference *fileRef = [self getReference:path];
|
||||
|
||||
|
||||
[fileRef downloadURLWithCompletion:^(NSURL * _Nullable URL, NSError * _Nullable error) {
|
||||
if (error != nil) {
|
||||
[self promiseRejectStorageException:reject error: error];
|
||||
@ -133,7 +135,7 @@ RCT_EXPORT_METHOD(getDownloadURL: (NSString *) path resolver:(RCTPromiseResolveB
|
||||
*/
|
||||
RCT_EXPORT_METHOD(getMetadata: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
FIRStorageReference *fileRef = [self getReference:path];
|
||||
|
||||
|
||||
[fileRef metadataWithCompletion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) {
|
||||
if (error != nil) {
|
||||
[self promiseRejectStorageException:reject error: error];
|
||||
@ -153,7 +155,7 @@ RCT_EXPORT_METHOD(getMetadata: (NSString *) path resolver:(RCTPromiseResolveBloc
|
||||
RCT_EXPORT_METHOD(updateMetadata: (NSString *) path metadata:(NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
FIRStorageReference *fileRef = [self getReference:path];
|
||||
FIRStorageMetadata *firmetadata = [[FIRStorageMetadata alloc] initWithDictionary:metadata];
|
||||
|
||||
|
||||
[fileRef updateMetadata:firmetadata completion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) {
|
||||
if (error != nil) {
|
||||
[self promiseRejectStorageException:reject error: error];
|
||||
@ -174,33 +176,33 @@ RCT_EXPORT_METHOD(downloadFile: (NSString *) path localPath:(NSString *) localPa
|
||||
FIRStorageReference *fileRef = [self getReference:path];
|
||||
NSURL *localFile = [NSURL fileURLWithPath:localPath];
|
||||
FIRStorageDownloadTask *downloadTask = [fileRef writeToFile:localFile];
|
||||
|
||||
|
||||
// listen for state changes, errors, and completion of the download.
|
||||
[downloadTask observeStatus:FIRStorageTaskStatusResume handler:^(FIRStorageTaskSnapshot *snapshot) {
|
||||
// download resumed, also fires when the upload starts
|
||||
NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot];
|
||||
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
|
||||
}];
|
||||
|
||||
|
||||
[downloadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) {
|
||||
// download paused
|
||||
NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot];
|
||||
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
|
||||
}];
|
||||
|
||||
|
||||
[downloadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) {
|
||||
// download reported progress
|
||||
NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot];
|
||||
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
|
||||
}];
|
||||
|
||||
|
||||
[downloadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) {
|
||||
// download completed successfully
|
||||
NSDictionary *resp = [self getDownloadTaskAsDictionary:snapshot];
|
||||
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_DOWNLOAD_SUCCESS props:resp];
|
||||
resolve(resp);
|
||||
}];
|
||||
|
||||
|
||||
[downloadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) {
|
||||
// download task failed
|
||||
// TODO sendJSError event
|
||||
@ -250,7 +252,7 @@ RCT_EXPORT_METHOD(setMaxUploadRetryTime:(NSNumber *) milliseconds) {
|
||||
RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath metadata:(NSDictionary *)metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
if ([localPath hasPrefix:@"assets-library://"] || [localPath hasPrefix:@"ph://"]) {
|
||||
PHFetchResult* assets;
|
||||
|
||||
|
||||
if ([localPath hasPrefix:@"assets-library://"]) {
|
||||
NSURL *localFile = [[NSURL alloc] initWithString:localPath];
|
||||
assets = [PHAsset fetchAssetsWithALAssetURLs:@[localFile] options:nil];
|
||||
@ -258,16 +260,16 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
|
||||
NSString *assetId = [localPath substringFromIndex:@"ph://".length];
|
||||
assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil];
|
||||
}
|
||||
|
||||
|
||||
PHAsset *asset = [assets firstObject];
|
||||
|
||||
|
||||
// this is based on http://stackoverflow.com/questions/35241449
|
||||
if (asset.mediaType == PHAssetMediaTypeImage) {
|
||||
// images
|
||||
PHImageRequestOptions *options = [PHImageRequestOptions new];
|
||||
options.networkAccessAllowed = true;
|
||||
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData * imageData, NSString * dataUTI, UIImageOrientation orientation, NSDictionary * info) {
|
||||
if ([info objectForKey:PHImageErrorKey] == nil) {
|
||||
if (info[PHImageErrorKey] == nil) {
|
||||
[self uploadData:imageData metadata:metadata path:path resolver:resolve rejecter:reject];
|
||||
} else {
|
||||
reject(@"storage/request-image-data-failed", @"Could not obtain image data for the specified file.", nil);
|
||||
@ -278,16 +280,16 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
|
||||
PHVideoRequestOptions *options = [PHVideoRequestOptions new];
|
||||
options.networkAccessAllowed = true;
|
||||
[[PHImageManager defaultManager] requestExportSessionForVideo:asset options:options exportPreset:AVAssetExportPresetHighestQuality resultHandler:^(AVAssetExportSession * _Nullable exportSession, NSDictionary * _Nullable info) {
|
||||
if ([info objectForKey:PHImageErrorKey] == nil) {
|
||||
if (info[PHImageErrorKey] == nil) {
|
||||
NSURL *tempUrl = [self temporaryFileUrl];
|
||||
exportSession.outputURL = tempUrl;
|
||||
|
||||
|
||||
NSArray<PHAssetResource *> *resources = [PHAssetResource assetResourcesForAsset:asset];
|
||||
for (PHAssetResource *resource in resources) {
|
||||
exportSession.outputFileType = resource.uniformTypeIdentifier;
|
||||
if (exportSession.outputFileType != nil) break;
|
||||
}
|
||||
|
||||
|
||||
[exportSession exportAsynchronouslyWithCompletionHandler:^{
|
||||
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
|
||||
[self uploadFile:tempUrl metadata:metadata path:path resolver:resolve rejecter:reject];
|
||||
@ -305,7 +307,7 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
|
||||
NSData *data = [[NSFileManager defaultManager] contentsAtPath:localPath];
|
||||
[self uploadData:data metadata:metadata path:path resolver:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (NSURL *) temporaryFileUrl {
|
||||
@ -334,7 +336,7 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
|
||||
NSDictionary *event = [self getUploadTaskAsDictionary:snapshot];
|
||||
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
|
||||
}];
|
||||
|
||||
|
||||
[uploadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) {
|
||||
// upload paused
|
||||
NSDictionary *event = [self getUploadTaskAsDictionary:snapshot];
|
||||
@ -345,7 +347,7 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
|
||||
NSDictionary *event = [self getUploadTaskAsDictionary:snapshot];
|
||||
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
|
||||
}];
|
||||
|
||||
|
||||
[uploadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) {
|
||||
// upload completed successfully
|
||||
NSDictionary *resp = [self getUploadTaskAsDictionary:snapshot];
|
||||
@ -353,7 +355,7 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
|
||||
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_UPLOAD_SUCCESS props:resp];
|
||||
resolve(resp);
|
||||
}];
|
||||
|
||||
|
||||
[uploadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) {
|
||||
if (snapshot.error != nil) {
|
||||
[self promiseRejectStorageException:reject error:snapshot.error];
|
||||
@ -445,3 +447,10 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
|
||||
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation RNFirebaseStorage
|
||||
RCT_EXPORT_MODULE();
|
||||
RCT_EXPORT_METHOD(nativeSDKMissing) {}
|
||||
@end
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-firebase",
|
||||
"version": "1.0.10",
|
||||
"version": "1.1.0",
|
||||
"author": "Invertase <contact@invertase.io> (http://invertase.io)",
|
||||
"description": "A react native firebase library supporting both android and ios native firebase SDK's",
|
||||
"main": "index",
|
||||
@ -74,7 +74,7 @@
|
||||
"eslint-plugin-import": "^2.0.1",
|
||||
"eslint-plugin-jsx-a11y": "^2.2.3",
|
||||
"eslint-plugin-react": "^6.4.1",
|
||||
"flow-bin": "^0.40.0",
|
||||
"flow-bin": "^0.46.0",
|
||||
"react": "^15.3.0",
|
||||
"react-dom": "^15.3.0",
|
||||
"react-native": "^0.44.0",
|
||||
|
Loading…
x
Reference in New Issue
Block a user