2
0
mirror of synced 2025-01-11 22:54:12 +00:00

Merge branch 'perf-mon' of github.com:invertase/react-native-firebase into perf-mon

This commit is contained in:
Elliot Hesp 2017-05-25 15:30:57 +01:00
commit 8df8f5a68c
11 changed files with 104 additions and 397 deletions

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,5 +1,4 @@
#import "RNFirebaseAuth.h"
#import "RNFirebaseErrors.h"
#import "RNFirebaseEvents.h"
@implementation RNFirebaseAuth

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 couldnt 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

View File

@ -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",