From 7c81a9af6b2bd0d1c8124af301d37ca641fc0da1 Mon Sep 17 00:00:00 2001 From: Edmundas Rakauskas Date: Wed, 8 Apr 2020 23:39:37 +0300 Subject: [PATCH 1/3] adding getInfo method for iOS which should return some firebase remote config settings and other info regarding last fetch timing and status --- src/ios/FirebasePlugin.h | 1 + src/ios/FirebasePlugin.m | 121 ++++++++++++++++++++++++--------------- 2 files changed, 77 insertions(+), 45 deletions(-) diff --git a/src/ios/FirebasePlugin.h b/src/ios/FirebasePlugin.h index 27d9e09c1..2f4c8085f 100644 --- a/src/ios/FirebasePlugin.h +++ b/src/ios/FirebasePlugin.h @@ -68,6 +68,7 @@ - (void)fetch:(CDVInvokedUrlCommand*)command; - (void)activateFetched:(CDVInvokedUrlCommand*)command; - (void)getValue:(CDVInvokedUrlCommand*)command; +- (void)getInfo:(CDVInvokedUrlCommand*)command; // Performance - (void)setPerformanceCollectionEnabled:(CDVInvokedUrlCommand*)command; diff --git a/src/ios/FirebasePlugin.m b/src/ios/FirebasePlugin.m index 53b41f3fb..1d26cf2ec 100644 --- a/src/ios/FirebasePlugin.m +++ b/src/ios/FirebasePlugin.m @@ -57,31 +57,31 @@ + (void) setFirestore:(FIRFirestore*) firestoreInstance{ - (void)pluginInitialize { NSLog(@"Starting Firebase plugin"); firebasePlugin = self; - + @try { preferences = [NSUserDefaults standardUserDefaults]; googlePlist = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]]; - + if(![self getGooglePlistFlagWithDefaultValue:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED defaultValue:YES]){ isCrashlyticsEnabled = [self getPreferenceFlag:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED]; }else{ isCrashlyticsEnabled = YES; [self setPreferenceFlag:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED flag:YES]; } - + if([self getGooglePlistFlagWithDefaultValue:FIREBASE_ANALYTICS_COLLECTION_ENABLED defaultValue:YES]){ [self setPreferenceFlag:FIREBASE_ANALYTICS_COLLECTION_ENABLED flag:YES]; } - + if([self getGooglePlistFlagWithDefaultValue:FIREBASE_PERFORMANCE_COLLECTION_ENABLED defaultValue:YES]){ [self setPreferenceFlag:FIREBASE_PERFORMANCE_COLLECTION_ENABLED flag:YES]; } - + // Check for permission and register for remote notifications if granted [self _hasPermission:^(BOOL result) {}]; - + [GIDSignIn sharedInstance].presentingViewController = self.viewController; - + authCredentials = [[NSMutableDictionary alloc] init]; }@catch (NSException *exception) { [self handlePluginExceptionWithoutContext:exception]; @@ -167,7 +167,7 @@ - (void)getToken:(CDVInvokedUrlCommand *)command { }else{ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description]; } - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }]; }@catch (NSException *exception) { @@ -200,7 +200,7 @@ - (NSString *)hexadecimalStringFromData:(NSData *)data if (dataLength == 0) { return nil; } - + const unsigned char *dataBuffer = data.bytes; NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)]; for (int i = 0; i < dataLength; ++i) { @@ -285,7 +285,7 @@ - (void)grantPermission:(CDVInvokedUrlCommand *)command { - (void)registerForRemoteNotifications { NSLog(@"registerForRemoteNotifications"); if(registeredForRemoteNotifications) return; - + [self runOnMainThread:^{ @try { [[UIApplication sharedApplication] registerForRemoteNotifications]; @@ -317,7 +317,7 @@ - (void)getBadgeNumber:(CDVInvokedUrlCommand *)command { [self runOnMainThread:^{ @try { long badge = [[UIApplication sharedApplication] applicationIconBadgeNumber]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:badge]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { @@ -476,7 +476,7 @@ - (void)clearAllNotifications:(CDVInvokedUrlCommand *)command { @try { [[UIApplication sharedApplication] setApplicationIconBadgeNumber:1]; [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { @@ -561,7 +561,7 @@ - (void)authenticateUserWithGoogle:(CDVInvokedUrlCommand*)command{ @try { self.googleSignInCallbackId = command.callbackId; [[GIDSignIn sharedInstance] signIn]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; [pluginResult setKeepCallbackAsBool:YES]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; @@ -576,13 +576,13 @@ - (void)authenticateUserWithApple:(CDVInvokedUrlCommand*)command{ if (@available(iOS 13.0, *)) { self.appleSignInCallbackId = command.callbackId; [self startSignInWithAppleFlow]; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; [pluginResult setKeepCallbackAsBool:YES]; } else { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"OS version is too low - Apple Sign In requires iOS 13.0+"]; } - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; @@ -593,7 +593,7 @@ - (void)signInWithCredential:(CDVInvokedUrlCommand*)command { @try { FIRAuthCredential* credential = [self obtainAuthCredential:[command.arguments objectAtIndex:0] command:command]; if(credential == nil) return; - + [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { @@ -611,10 +611,10 @@ - (void)reauthenticateWithCredential:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + FIRAuthCredential* credential = [self obtainAuthCredential:[command.arguments objectAtIndex:0] command:command]; if(credential == nil) return; - + [user reauthenticateWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { [self handleAuthResult:authResult error:error command:command]; }]; @@ -627,13 +627,13 @@ - (void)linkUserWithCredential:(CDVInvokedUrlCommand*)command { @try { FIRAuthCredential* credential = [self obtainAuthCredential:[command.arguments objectAtIndex:0] command:command]; if(credential == nil) return; - + [[FIRAuth auth].currentUser linkWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { [self handleAuthResult:authResult error:error command:command]; }]; - + }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } @@ -643,7 +643,7 @@ - (void)isUserSignedIn:(CDVInvokedUrlCommand*)command { @try { bool isSignedIn = [FIRAuth auth].currentUser ? true : false; [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:isSignedIn] callbackId:command.callbackId]; - + }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } @@ -656,12 +656,12 @@ - (void)signOutUser:(CDVInvokedUrlCommand*)command { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + // Sign out of Google if([[GIDSignIn sharedInstance] currentUser] != nil){ [[GIDSignIn sharedInstance] signOut]; } - + // Sign out of Firebase NSError *signOutError; BOOL status = [[FIRAuth auth] signOut:&signOutError]; @@ -676,14 +676,14 @@ - (void)signOutUser:(CDVInvokedUrlCommand*)command { } - (void)getCurrentUser:(CDVInvokedUrlCommand *)command { - + @try { FIRUser* user = [FIRAuth auth].currentUser; if(!user){ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSMutableDictionary* userInfo = [NSMutableDictionary new]; [userInfo setValue:user.displayName forKey:@"name"]; [userInfo setValue:user.email forKey:@"email"]; @@ -708,9 +708,9 @@ - (void)updateUserProfile:(CDVInvokedUrlCommand*)command { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSDictionary* profile = [command.arguments objectAtIndex:0]; - + FIRUserProfileChangeRequest* changeRequest = [user profileChangeRequest]; if([profile objectForKey:@"name"] != nil){ changeRequest.displayName = [profile objectForKey:@"name"]; @@ -718,7 +718,7 @@ - (void)updateUserProfile:(CDVInvokedUrlCommand*)command { if([profile objectForKey:@"photoUri"] != nil){ changeRequest.photoURL = [NSURL URLWithString:[profile objectForKey:@"photoUri"]]; } - + [changeRequest commitChangesWithCompletion:^(NSError *_Nullable error) { @try { [self handleResultWithPotentialError:error command:command]; @@ -738,7 +738,7 @@ - (void)updateUserEmail:(CDVInvokedUrlCommand*)command { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSString* email = [command.arguments objectAtIndex:0]; [user updateEmail:email completion:^(NSError *_Nullable error) { @try { @@ -759,7 +759,7 @@ - (void)sendUserEmailVerification:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + [user sendEmailVerificationWithCompletion:^(NSError *_Nullable error) { @try { [self handleResultWithPotentialError:error command:command]; @@ -779,7 +779,7 @@ - (void)updateUserPassword:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSString* password = [command.arguments objectAtIndex:0]; [user updatePassword:password completion:^(NSError *_Nullable error) { @try { @@ -815,7 +815,7 @@ - (void)deleteUser:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + [user deleteWithCompletion:^(NSError *_Nullable error) { @try { [self handleResultWithPotentialError:error command:command]; @@ -1006,7 +1006,7 @@ - (void)setCrashlyticsCollectionEnabled:(CDVInvokedUrlCommand *)command { [self setPreferenceFlag:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED flag:enabled]; pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; } - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; @@ -1039,7 +1039,7 @@ - (void)isCrashlyticsCollectionCurrentlyEnabled:(CDVInvokedUrlCommand*)command{ - (void)logError:(CDVInvokedUrlCommand *)command { [self.commandDelegate runInBackground:^{ NSString* errorMessage = [command.arguments objectAtIndex:0]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; @try { if(!isCrashlyticsEnabled){ @@ -1048,11 +1048,11 @@ - (void)logError:(CDVInvokedUrlCommand *)command { // We can optionally be passed a stack trace from stackTrace.js which we'll put in userInfo. else if ([command.arguments count] > 1) { NSArray* stackFrames = [command.arguments objectAtIndex:1]; - + NSString* message = errorMessage; NSString* name = @"Uncaught Javascript exception"; NSMutableArray *customFrames = [[NSMutableArray alloc] init]; - + for (NSDictionary* stackFrame in stackFrames) { CLSStackFrame *customFrame = [CLSStackFrame stackFrame]; [customFrame setSymbol:stackFrame[@"functionName"]]; @@ -1073,7 +1073,7 @@ - (void)logError:(CDVInvokedUrlCommand *)command { } @catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } - + }]; } @@ -1187,6 +1187,37 @@ - (void)getValue:(CDVInvokedUrlCommand *)command { }]; } +- (void)getInfo:(CDVInvokedUrlCommand *)command { + [self.commandDelegate runInBackground:^{ + @try { + FIRRemoteConfig* remoteConfig = [FIRRemoteConfig remoteConfig]; + NSInteger minimumFetchInterval = remoteConfig.configSettings.minimumFetchInterval; + NSInteger fetchTimeout = remoteConfig.configSettings.fetchTimeout; + NSDate* lastFetchTime = remoteConfig.lastFetchTime; + FIRRemoteConfigFetchStatus lastFetchStatus = remoteConfig.lastFetchStatus; + // isDeveloperModeEnabled is deprecated new recommnded way to check is minimumFetchInterval == 0 + BOOL isDeveloperModeEnabled = minimumFetchInterval == 0 ? true : false; + + NSDictionary* configSettings = @{ + @"developerModeEnabled": [NSNumber numberWithBool:isDeveloperModeEnabled], + @"minimumFetchInterval": [NSNumber numberWithInteger:minimumFetchInterval], + @"fetchTimeout": [NSNumber numberWithInteger:fetchTimeout], + }; + + NSDictionary* infoObject = @{ + @"configSettings": configSettings, + @"fetchTimeMillis": (lastFetchTime ? [NSNumber numberWithInteger:(lastFetchTime.timeIntervalSince1970 * 1000)] : [NSNull null]), + @"lastFetchStatus": [NSNumber numberWithInteger:(lastFetchStatus)], + }; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:infoObject]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }@catch (NSException *exception) { + [self handlePluginExceptionWithContext:exception :command]; + } + }]; +} + /* * Performance */ @@ -1324,7 +1355,7 @@ - (void)setDocumentInFirestoreCollection:(CDVInvokedUrlCommand*)command { NSString* documentId = [command.arguments objectAtIndex:0]; NSDictionary* document = [command.arguments objectAtIndex:1]; NSString* collection = [command.arguments objectAtIndex:2]; - + [[[firestore collectionWithPath:collection] documentWithPath:documentId] setData:document completion:^(NSError * _Nullable error) { if (error != nil) { [self sendPluginError:error.localizedDescription:command]; @@ -1344,7 +1375,7 @@ - (void)updateDocumentInFirestoreCollection:(CDVInvokedUrlCommand*)command { NSString* documentId = [command.arguments objectAtIndex:0]; NSDictionary* document = [command.arguments objectAtIndex:1]; NSString* collection = [command.arguments objectAtIndex:2]; - + FIRDocumentReference* docRef = [[firestore collectionWithPath:collection] documentWithPath:documentId]; if(docRef != nil){ [docRef updateData:document completion:^(NSError * _Nullable error) { @@ -1388,7 +1419,7 @@ - (void)documentExistsInFirestoreCollection:(CDVInvokedUrlCommand*)command { @try { NSString* documentId = [command.arguments objectAtIndex:0]; NSString* collection = [command.arguments objectAtIndex:1]; - + FIRDocumentReference* docRef = [[firestore collectionWithPath:collection] documentWithPath:documentId]; if(docRef != nil){ [docRef getDocumentWithCompletion:^(FIRDocumentSnapshot * _Nullable snapshot, NSError * _Nullable error) { @@ -1413,7 +1444,7 @@ - (void)fetchDocumentInFirestoreCollection:(CDVInvokedUrlCommand*)command { @try { NSString* documentId = [command.arguments objectAtIndex:0]; NSString* collection = [command.arguments objectAtIndex:1]; - + FIRDocumentReference* docRef = [[firestore collectionWithPath:collection] documentWithPath:documentId]; if(docRef != nil){ [docRef getDocumentWithCompletion:^(FIRDocumentSnapshot * _Nullable snapshot, NSError * _Nullable error) { @@ -1530,17 +1561,17 @@ - (void)runOnMainThread:(void (^)(void))completeBlock { - (FIRAuthCredential*)obtainAuthCredential:(NSDictionary*)credential command:(CDVInvokedUrlCommand *)command { FIRAuthCredential* authCredential = nil; - + if(credential == nil){ NSString* errMsg = @"credential object must be passed as first and only argument"; [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errMsg] callbackId:command.callbackId]; return authCredential; } - + NSString* key = [credential objectForKey:@"id"]; NSString* verificationId = [credential objectForKey:@"verificationId"]; NSString* code = [credential objectForKey:@"code"]; - + if(key != nil){ authCredential = [authCredentials objectForKey:key]; if(authCredential == nil){ @@ -1580,7 +1611,7 @@ - (int) saveAuthCredential: (FIRAuthCredential*) authCredential { while (key < 0 || [authCredentials objectForKey:[NSNumber numberWithInt:key]] != nil) { key = arc4random_uniform(100000); } - + [authCredentials setObject:authCredential forKey:[NSNumber numberWithInt:key]]; return key; From ee6b91f0af23798218122e3b38b7f2c4d62400bf Mon Sep 17 00:00:00 2001 From: Edmundas Rakauskas Date: Thu, 9 Apr 2020 00:07:54 +0300 Subject: [PATCH 2/3] updated getInfo readme --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1533e2568..864201b35 100644 --- a/README.md +++ b/README.md @@ -2469,7 +2469,6 @@ FirebasePlugin.getByteArray("key", function(bytes) { ``` ### getInfo -Android only. Get the current state of the FirebaseRemoteConfig singleton object: **Parameters**: @@ -2480,6 +2479,10 @@ Get the current state of the FirebaseRemoteConfig singleton object: FirebasePlugin.getInfo(function(info) { // the status of the developer mode setting (true/false) console.log(info.configSettings.developerModeEnabled); + // (iOS only) for how much (secs) fetch cache is valid and data will not be refetched + console.log(info.configSettings.minimumFetchInterval); + // (iOS only) value in seconds to abandon a pending fetch request made to the backend + console.log(info.configSettings.fetchTimeout); // the timestamp (milliseconds since epoch) of the last successful fetch console.log(info.fetchTimeMillis); // the status of the most recent fetch attempt (int) From d9bd6ea75a98e3ece5de008abece54b6b46d6752 Mon Sep 17 00:00:00 2001 From: Edmundas Rakauskas Date: Thu, 9 Apr 2020 00:11:09 +0300 Subject: [PATCH 3/3] restoring previous whitespace --- src/ios/FirebasePlugin.m | 90 ++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/ios/FirebasePlugin.m b/src/ios/FirebasePlugin.m index 1d26cf2ec..58ee06795 100644 --- a/src/ios/FirebasePlugin.m +++ b/src/ios/FirebasePlugin.m @@ -57,31 +57,31 @@ + (void) setFirestore:(FIRFirestore*) firestoreInstance{ - (void)pluginInitialize { NSLog(@"Starting Firebase plugin"); firebasePlugin = self; - + @try { preferences = [NSUserDefaults standardUserDefaults]; googlePlist = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]]; - + if(![self getGooglePlistFlagWithDefaultValue:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED defaultValue:YES]){ isCrashlyticsEnabled = [self getPreferenceFlag:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED]; }else{ isCrashlyticsEnabled = YES; [self setPreferenceFlag:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED flag:YES]; } - + if([self getGooglePlistFlagWithDefaultValue:FIREBASE_ANALYTICS_COLLECTION_ENABLED defaultValue:YES]){ [self setPreferenceFlag:FIREBASE_ANALYTICS_COLLECTION_ENABLED flag:YES]; } - + if([self getGooglePlistFlagWithDefaultValue:FIREBASE_PERFORMANCE_COLLECTION_ENABLED defaultValue:YES]){ [self setPreferenceFlag:FIREBASE_PERFORMANCE_COLLECTION_ENABLED flag:YES]; } - + // Check for permission and register for remote notifications if granted [self _hasPermission:^(BOOL result) {}]; - + [GIDSignIn sharedInstance].presentingViewController = self.viewController; - + authCredentials = [[NSMutableDictionary alloc] init]; }@catch (NSException *exception) { [self handlePluginExceptionWithoutContext:exception]; @@ -167,7 +167,7 @@ - (void)getToken:(CDVInvokedUrlCommand *)command { }else{ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description]; } - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }]; }@catch (NSException *exception) { @@ -200,7 +200,7 @@ - (NSString *)hexadecimalStringFromData:(NSData *)data if (dataLength == 0) { return nil; } - + const unsigned char *dataBuffer = data.bytes; NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)]; for (int i = 0; i < dataLength; ++i) { @@ -285,7 +285,7 @@ - (void)grantPermission:(CDVInvokedUrlCommand *)command { - (void)registerForRemoteNotifications { NSLog(@"registerForRemoteNotifications"); if(registeredForRemoteNotifications) return; - + [self runOnMainThread:^{ @try { [[UIApplication sharedApplication] registerForRemoteNotifications]; @@ -317,7 +317,7 @@ - (void)getBadgeNumber:(CDVInvokedUrlCommand *)command { [self runOnMainThread:^{ @try { long badge = [[UIApplication sharedApplication] applicationIconBadgeNumber]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:badge]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { @@ -476,7 +476,7 @@ - (void)clearAllNotifications:(CDVInvokedUrlCommand *)command { @try { [[UIApplication sharedApplication] setApplicationIconBadgeNumber:1]; [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { @@ -561,7 +561,7 @@ - (void)authenticateUserWithGoogle:(CDVInvokedUrlCommand*)command{ @try { self.googleSignInCallbackId = command.callbackId; [[GIDSignIn sharedInstance] signIn]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; [pluginResult setKeepCallbackAsBool:YES]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; @@ -576,13 +576,13 @@ - (void)authenticateUserWithApple:(CDVInvokedUrlCommand*)command{ if (@available(iOS 13.0, *)) { self.appleSignInCallbackId = command.callbackId; [self startSignInWithAppleFlow]; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; [pluginResult setKeepCallbackAsBool:YES]; } else { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"OS version is too low - Apple Sign In requires iOS 13.0+"]; } - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; @@ -593,7 +593,7 @@ - (void)signInWithCredential:(CDVInvokedUrlCommand*)command { @try { FIRAuthCredential* credential = [self obtainAuthCredential:[command.arguments objectAtIndex:0] command:command]; if(credential == nil) return; - + [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { @@ -611,10 +611,10 @@ - (void)reauthenticateWithCredential:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + FIRAuthCredential* credential = [self obtainAuthCredential:[command.arguments objectAtIndex:0] command:command]; if(credential == nil) return; - + [user reauthenticateWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { [self handleAuthResult:authResult error:error command:command]; }]; @@ -627,13 +627,13 @@ - (void)linkUserWithCredential:(CDVInvokedUrlCommand*)command { @try { FIRAuthCredential* credential = [self obtainAuthCredential:[command.arguments objectAtIndex:0] command:command]; if(credential == nil) return; - + [[FIRAuth auth].currentUser linkWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { [self handleAuthResult:authResult error:error command:command]; }]; - + }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } @@ -643,7 +643,7 @@ - (void)isUserSignedIn:(CDVInvokedUrlCommand*)command { @try { bool isSignedIn = [FIRAuth auth].currentUser ? true : false; [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:isSignedIn] callbackId:command.callbackId]; - + }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } @@ -656,12 +656,12 @@ - (void)signOutUser:(CDVInvokedUrlCommand*)command { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + // Sign out of Google if([[GIDSignIn sharedInstance] currentUser] != nil){ [[GIDSignIn sharedInstance] signOut]; } - + // Sign out of Firebase NSError *signOutError; BOOL status = [[FIRAuth auth] signOut:&signOutError]; @@ -676,14 +676,14 @@ - (void)signOutUser:(CDVInvokedUrlCommand*)command { } - (void)getCurrentUser:(CDVInvokedUrlCommand *)command { - + @try { FIRUser* user = [FIRAuth auth].currentUser; if(!user){ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSMutableDictionary* userInfo = [NSMutableDictionary new]; [userInfo setValue:user.displayName forKey:@"name"]; [userInfo setValue:user.email forKey:@"email"]; @@ -708,9 +708,9 @@ - (void)updateUserProfile:(CDVInvokedUrlCommand*)command { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSDictionary* profile = [command.arguments objectAtIndex:0]; - + FIRUserProfileChangeRequest* changeRequest = [user profileChangeRequest]; if([profile objectForKey:@"name"] != nil){ changeRequest.displayName = [profile objectForKey:@"name"]; @@ -718,7 +718,7 @@ - (void)updateUserProfile:(CDVInvokedUrlCommand*)command { if([profile objectForKey:@"photoUri"] != nil){ changeRequest.photoURL = [NSURL URLWithString:[profile objectForKey:@"photoUri"]]; } - + [changeRequest commitChangesWithCompletion:^(NSError *_Nullable error) { @try { [self handleResultWithPotentialError:error command:command]; @@ -738,7 +738,7 @@ - (void)updateUserEmail:(CDVInvokedUrlCommand*)command { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSString* email = [command.arguments objectAtIndex:0]; [user updateEmail:email completion:^(NSError *_Nullable error) { @try { @@ -759,7 +759,7 @@ - (void)sendUserEmailVerification:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + [user sendEmailVerificationWithCompletion:^(NSError *_Nullable error) { @try { [self handleResultWithPotentialError:error command:command]; @@ -779,7 +779,7 @@ - (void)updateUserPassword:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + NSString* password = [command.arguments objectAtIndex:0]; [user updatePassword:password completion:^(NSError *_Nullable error) { @try { @@ -815,7 +815,7 @@ - (void)deleteUser:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No user is currently signed"] callbackId:command.callbackId]; return; } - + [user deleteWithCompletion:^(NSError *_Nullable error) { @try { [self handleResultWithPotentialError:error command:command]; @@ -1006,7 +1006,7 @@ - (void)setCrashlyticsCollectionEnabled:(CDVInvokedUrlCommand *)command { [self setPreferenceFlag:FIREBASE_CRASHLYTICS_COLLECTION_ENABLED flag:enabled]; pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; } - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }@catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; @@ -1039,7 +1039,7 @@ - (void)isCrashlyticsCollectionCurrentlyEnabled:(CDVInvokedUrlCommand*)command{ - (void)logError:(CDVInvokedUrlCommand *)command { [self.commandDelegate runInBackground:^{ NSString* errorMessage = [command.arguments objectAtIndex:0]; - + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; @try { if(!isCrashlyticsEnabled){ @@ -1048,11 +1048,11 @@ - (void)logError:(CDVInvokedUrlCommand *)command { // We can optionally be passed a stack trace from stackTrace.js which we'll put in userInfo. else if ([command.arguments count] > 1) { NSArray* stackFrames = [command.arguments objectAtIndex:1]; - + NSString* message = errorMessage; NSString* name = @"Uncaught Javascript exception"; NSMutableArray *customFrames = [[NSMutableArray alloc] init]; - + for (NSDictionary* stackFrame in stackFrames) { CLSStackFrame *customFrame = [CLSStackFrame stackFrame]; [customFrame setSymbol:stackFrame[@"functionName"]]; @@ -1073,7 +1073,7 @@ - (void)logError:(CDVInvokedUrlCommand *)command { } @catch (NSException *exception) { [self handlePluginExceptionWithContext:exception :command]; } - + }]; } @@ -1355,7 +1355,7 @@ - (void)setDocumentInFirestoreCollection:(CDVInvokedUrlCommand*)command { NSString* documentId = [command.arguments objectAtIndex:0]; NSDictionary* document = [command.arguments objectAtIndex:1]; NSString* collection = [command.arguments objectAtIndex:2]; - + [[[firestore collectionWithPath:collection] documentWithPath:documentId] setData:document completion:^(NSError * _Nullable error) { if (error != nil) { [self sendPluginError:error.localizedDescription:command]; @@ -1375,7 +1375,7 @@ - (void)updateDocumentInFirestoreCollection:(CDVInvokedUrlCommand*)command { NSString* documentId = [command.arguments objectAtIndex:0]; NSDictionary* document = [command.arguments objectAtIndex:1]; NSString* collection = [command.arguments objectAtIndex:2]; - + FIRDocumentReference* docRef = [[firestore collectionWithPath:collection] documentWithPath:documentId]; if(docRef != nil){ [docRef updateData:document completion:^(NSError * _Nullable error) { @@ -1419,7 +1419,7 @@ - (void)documentExistsInFirestoreCollection:(CDVInvokedUrlCommand*)command { @try { NSString* documentId = [command.arguments objectAtIndex:0]; NSString* collection = [command.arguments objectAtIndex:1]; - + FIRDocumentReference* docRef = [[firestore collectionWithPath:collection] documentWithPath:documentId]; if(docRef != nil){ [docRef getDocumentWithCompletion:^(FIRDocumentSnapshot * _Nullable snapshot, NSError * _Nullable error) { @@ -1444,7 +1444,7 @@ - (void)fetchDocumentInFirestoreCollection:(CDVInvokedUrlCommand*)command { @try { NSString* documentId = [command.arguments objectAtIndex:0]; NSString* collection = [command.arguments objectAtIndex:1]; - + FIRDocumentReference* docRef = [[firestore collectionWithPath:collection] documentWithPath:documentId]; if(docRef != nil){ [docRef getDocumentWithCompletion:^(FIRDocumentSnapshot * _Nullable snapshot, NSError * _Nullable error) { @@ -1561,17 +1561,17 @@ - (void)runOnMainThread:(void (^)(void))completeBlock { - (FIRAuthCredential*)obtainAuthCredential:(NSDictionary*)credential command:(CDVInvokedUrlCommand *)command { FIRAuthCredential* authCredential = nil; - + if(credential == nil){ NSString* errMsg = @"credential object must be passed as first and only argument"; [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errMsg] callbackId:command.callbackId]; return authCredential; } - + NSString* key = [credential objectForKey:@"id"]; NSString* verificationId = [credential objectForKey:@"verificationId"]; NSString* code = [credential objectForKey:@"code"]; - + if(key != nil){ authCredential = [authCredentials objectForKey:key]; if(authCredential == nil){ @@ -1611,7 +1611,7 @@ - (int) saveAuthCredential: (FIRAuthCredential*) authCredential { while (key < 0 || [authCredentials objectForKey:[NSNumber numberWithInt:key]] != nil) { key = arc4random_uniform(100000); } - + [authCredentials setObject:authCredential forKey:[NSNumber numberWithInt:key]]; return key;