diff --git a/ios/RNFirebase/invites/RNFirebaseInvites.h b/ios/RNFirebase/invites/RNFirebaseInvites.h index ddeda5ac..5987dbf3 100644 --- a/ios/RNFirebase/invites/RNFirebaseInvites.h +++ b/ios/RNFirebase/invites/RNFirebaseInvites.h @@ -14,10 +14,11 @@ @property _Nullable RCTPromiseRejectBlock invitationsRejecter; @property _Nullable RCTPromiseResolveBlock invitationsResolver; -#if !TARGET_OS_TV -- (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo; -- (void)didRegisterUserNotificationSettings:(nonnull UIUserNotificationSettings *)notificationSettings; -#endif +- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options; + +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; + +- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler; @end @@ -27,3 +28,4 @@ #endif #endif + diff --git a/ios/RNFirebase/invites/RNFirebaseInvites.m b/ios/RNFirebase/invites/RNFirebaseInvites.m index 2d064436..76ad8b1b 100644 --- a/ios/RNFirebase/invites/RNFirebaseInvites.m +++ b/ios/RNFirebase/invites/RNFirebaseInvites.m @@ -2,6 +2,7 @@ #if __has_include() #import "RNFirebaseEvents.h" +#import "RNFirebaseUtil.h" #import #import @@ -32,21 +33,34 @@ RCT_EXPORT_MODULE() // ** Start AppDelegate methods // ******************************************************* -// Listen for permission response -- (void) didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { - +- (BOOL)application:(UIApplication *)app + openURL:(NSURL *)url + options:(NSDictionary *)options { + return [self application:app + openURL:url + sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] + annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; } -// Listen for FCM data messages that arrive as a remote notification -- (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo { - +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation { + return [self handleUrl:url]; } +- (BOOL)application:(UIApplication *)application +continueUserActivity:(NSUserActivity *)userActivity + restorationHandler:(void (^)(NSArray *))restorationHandler { + if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { + return [self handleUrl:userActivity.webpageURL]; + } + return NO; +} // ******************************************************* // ** Finish AppDelegate methods // ******************************************************* - // ******************************************************* // ** Start FIRInviteDelegate methods // ******************************************************* @@ -54,9 +68,13 @@ RCT_EXPORT_MODULE() // Listen for invitation response - (void)inviteFinishedWithInvitations:(NSArray *)invitationIds error:(NSError *)error { if (error) { - _invitationsRejecter(@"invites/invitation-error", @"Invitation failed to send", error); - } else if (invitationIds.count == 0) { - _invitationsRejecter(@"invites/invitation-cancelled", @"Invitation cancelled", nil); + if (error.code == -402) { + _invitationsRejecter(@"invites/invitation-cancelled", @"Invitation cancelled", nil); + } else if (error.code == -404) { + _invitationsRejecter(@"invites/invitation-error", @"User must be signed in with GoogleSignIn", nil); + } else { + _invitationsRejecter(@"invites/invitation-error", @"Invitation failed to send", error); + } } else { _invitationsResolver(invitationIds); } @@ -70,13 +88,40 @@ RCT_EXPORT_MODULE() // ** Start React Module methods ** RCT_EXPORT_METHOD(getInitialInvitation:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - // TODO - resolve(nil); + NSURL* url = nil; + if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) { + url = (NSURL*)self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]; + } else if (self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]) { + NSDictionary *dictionary = + self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]; + if ([dictionary[UIApplicationLaunchOptionsUserActivityTypeKey] isEqual:NSUserActivityTypeBrowsingWeb]) { + NSUserActivity* userActivity = (NSUserActivity*) dictionary[@"UIApplicationLaunchOptionsUserActivityKey"]; + url = userActivity.webpageURL; + } + } + + if (url) { + [FIRInvites handleUniversalLink:url completion:^(FIRReceivedInvite * _Nullable receivedInvite, NSError * _Nullable error) { + if (error) { + NSLog(@"Failed to handle universal link: %@", [error localizedDescription]); + reject(@"invites/initial-invitation-error", @"Failed to handle invitation", error); + } else if (receivedInvite) { + resolve(@{ + @"deepLink": receivedInvite.deepLink, + @"invitationId": receivedInvite.inviteId, + }); + } else { + resolve(nil); + } + }]; + } else { + resolve(nil); + } } RCT_EXPORT_METHOD(sendInvitation:(NSDictionary *) invitation - resolve:(RCTPromiseResolveBlock) resolve - reject:(RCTPromiseRejectBlock) reject) { + resolve:(RCTPromiseResolveBlock) resolve + reject:(RCTPromiseRejectBlock) reject) { if (!invitation[@"message"]) { reject(@"invites/invalid-invitation", @"The supplied invitation is missing a 'message' field", nil); } @@ -111,10 +156,25 @@ RCT_EXPORT_METHOD(sendInvitation:(NSDictionary *) invitation _invitationsResolver = resolve; // Open the invitation dialog - [inviteDialog open]; + dispatch_async(dispatch_get_main_queue(), ^{ + [inviteDialog open]; + }); } // ** Start internals ** +- (BOOL)handleUrl:(NSURL *)url { + return [FIRInvites handleUniversalLink:url completion:^(FIRReceivedInvite * _Nullable receivedInvite, NSError * _Nullable error) { + if (error) { + NSLog(@"Failed to handle invitation: %@", [error localizedDescription]); + } else if (receivedInvite) { + [RNFirebaseUtil sendJSEvent:self name:LINKS_LINK_RECEIVED body:@{ + @"deepLink": receivedInvite.deepLink, + @"invitationId": receivedInvite.inviteId, + }]; + } + }]; +} + - (NSArray *)supportedEvents { return @[INVITES_INVITATION_RECEIVED];