diff --git a/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinks.java b/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinks.java index 7734513f..746dcf9b 100644 --- a/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinks.java +++ b/android/src/main/java/io/invertase/firebase/links/RNFirebaseLinks.java @@ -175,7 +175,7 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ // Looks at the internals of the link data to detect whether it's an invitation or not private boolean isInvitation(PendingDynamicLinkData pendingDynamicLinkData) { - return pendingDynamicLinkData.zzcbj().getString("com.google.firebase.appinvite.fdl.extension.InvitationId") != null; + return FirebaseAppInvite.getInvitation(pendingDynamicLinkData) != null; } private DynamicLink.Builder getDynamicLinkBuilderFromMap(final Map metaData) { diff --git a/ios/RNFirebase.xcodeproj/project.pbxproj b/ios/RNFirebase.xcodeproj/project.pbxproj index 46815506..b548d583 100644 --- a/ios/RNFirebase.xcodeproj/project.pbxproj +++ b/ios/RNFirebase.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ 839D91721EF3E20B0077C7C8 /* RNFirebaseCrash.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D915F1EF3E20A0077C7C8 /* RNFirebaseCrash.m */; }; 839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */; }; 839D91751EF3E20B0077C7C8 /* RNFirebasePerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.m */; }; + 83AAA0792063DEC2007EC5F7 /* RNFirebaseInvites.m in Sources */ = {isa = PBXBuildFile; fileRef = 83AAA0772063DEC2007EC5F7 /* RNFirebaseInvites.m */; }; 83C3EEEE1FA1EACC00B64D3C /* RNFirebaseUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 83C3EEEC1FA1EACC00B64D3C /* RNFirebaseUtil.m */; }; BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = BA84AE561FA9E59800E79390 /* RNFirebaseStorage.m */; }; D950369E1D19C77400F7094D /* RNFirebase.m in Sources */ = {isa = PBXBuildFile; fileRef = D950369D1D19C77400F7094D /* RNFirebase.m */; }; @@ -93,6 +94,8 @@ 839D91671EF3E20A0077C7C8 /* RNFirebasePerformance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebasePerformance.h; sourceTree = ""; }; 839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebasePerformance.m; sourceTree = ""; }; 839D91771EF3E22F0077C7C8 /* RNFirebaseEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseEvents.h; path = RNFirebase/RNFirebaseEvents.h; sourceTree = ""; }; + 83AAA0772063DEC2007EC5F7 /* RNFirebaseInvites.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseInvites.m; sourceTree = ""; }; + 83AAA0782063DEC2007EC5F7 /* RNFirebaseInvites.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseInvites.h; sourceTree = ""; }; 83C3EEEC1FA1EACC00B64D3C /* RNFirebaseUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNFirebaseUtil.m; path = RNFirebase/RNFirebaseUtil.m; sourceTree = ""; }; 83C3EEED1FA1EACC00B64D3C /* RNFirebaseUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseUtil.h; path = RNFirebase/RNFirebaseUtil.h; sourceTree = ""; }; BA84AE551FA9E59800E79390 /* RNFirebaseStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseStorage.h; sourceTree = ""; }; @@ -133,6 +136,7 @@ 58B511D21A9E6C8500147676 = { isa = PBXGroup; children = ( + 83AAA0762063DEC2007EC5F7 /* invites */, 838E372420231E15004DCD3A /* notifications */, 838E372020231DF0004DCD3A /* instanceid */, 8336930F1FD80DE800AA806B /* fabric */, @@ -301,6 +305,16 @@ path = RNFirebase/perf; sourceTree = ""; }; + 83AAA0762063DEC2007EC5F7 /* invites */ = { + isa = PBXGroup; + children = ( + 83AAA0772063DEC2007EC5F7 /* RNFirebaseInvites.m */, + 83AAA0782063DEC2007EC5F7 /* RNFirebaseInvites.h */, + ); + name = invites; + path = RNFirebase/invites; + sourceTree = ""; + }; BA84AE541FA9E59800E79390 /* storage */ = { isa = PBXGroup; children = ( @@ -384,6 +398,7 @@ 839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */, 838E372720231E15004DCD3A /* RNFirebaseNotifications.m in Sources */, BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */, + 83AAA0792063DEC2007EC5F7 /* RNFirebaseInvites.m in Sources */, 8323CF071F6FBD870071420B /* NativeExpressComponent.m in Sources */, 83C3EEEE1FA1EACC00B64D3C /* RNFirebaseUtil.m in Sources */, 839D91721EF3E20B0077C7C8 /* RNFirebaseCrash.m in Sources */, diff --git a/ios/RNFirebase/invites/RNFirebaseInvites.h b/ios/RNFirebase/invites/RNFirebaseInvites.h new file mode 100644 index 00000000..1554834e --- /dev/null +++ b/ios/RNFirebase/invites/RNFirebaseInvites.h @@ -0,0 +1,27 @@ +#ifndef RNFirebaseInvites_h +#define RNFirebaseInvites_h +#import + +#if __has_include() +#import +#import +#import + +@interface RNFirebaseInvites : RCTEventEmitter + ++ (_Nonnull instancetype)instance; + +@property _Nullable RCTPromiseRejectBlock invitationsRejecter; +@property _Nullable RCTPromiseResolveBlock invitationsResolver; + +- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options; +- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler; + +@end + +#else +@interface RNFirebaseInvites : NSObject +@end +#endif + +#endif diff --git a/ios/RNFirebase/invites/RNFirebaseInvites.m b/ios/RNFirebase/invites/RNFirebaseInvites.m new file mode 100644 index 00000000..98f47561 --- /dev/null +++ b/ios/RNFirebase/invites/RNFirebaseInvites.m @@ -0,0 +1,186 @@ +#import "RNFirebaseInvites.h" + +#if __has_include() +#import "RNFirebaseEvents.h" +#import "RNFirebaseLinks.h" +#import "RNFirebaseUtil.h" +#import + +#import +#import +#import + +@implementation RNFirebaseInvites + +static RNFirebaseInvites *theRNFirebaseInvites = nil; + ++ (nonnull instancetype)instance { + return theRNFirebaseInvites; +} + +RCT_EXPORT_MODULE() + +- (id)init { + self = [super init]; + if (self != nil) { + NSLog(@"Setting up RNFirebaseInvites instance"); + // Set static instance for use from AppDelegate + theRNFirebaseInvites = self; + } + return self; +} + +// ******************************************************* +// ** Start AppDelegate methods +// ******************************************************* + +- (BOOL)application:(UIApplication *)app + openURL:(NSURL *)url + options:(NSDictionary *)options { + 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 +// ******************************************************* + +// Listen for invitation response +- (void)inviteFinishedWithInvitations:(NSArray *)invitationIds error:(NSError *)error { + if (error) { + 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); + } + _invitationsRejecter = nil; + _invitationsResolver = nil; +} + +// ******************************************************* +// ** Finish FIRInviteDelegate methods +// ******************************************************* + +// ** Start React Module methods ** +RCT_EXPORT_METHOD(getInitialInvitation:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { + 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 && receivedInvite.inviteId) { + 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) { + if (!invitation[@"message"]) { + reject(@"invites/invalid-invitation", @"The supplied invitation is missing a 'message' field", nil); + } + if (!invitation[@"title"]) { + reject(@"invites/invalid-invitation", @"The supplied invitation is missing a 'title' field", nil); + } + id inviteDialog = [FIRInvites inviteDialog]; + [inviteDialog setInviteDelegate: self]; + [inviteDialog setMessage:invitation[@"message"]]; + [inviteDialog setTitle:invitation[@"title"]]; + + if (invitation[@"androidClientId"]) { + FIRInvitesTargetApplication *targetApplication = [[FIRInvitesTargetApplication alloc] init]; + targetApplication.androidClientID = invitation[@"androidClientId"]; + [inviteDialog setOtherPlatformsTargetApplication:targetApplication]; + } + if (invitation[@"androidMinimumVersionCode"]) { + [inviteDialog setAndroidMinimumVersionCode:invitation[@"androidMinimumVersionCode"]]; + } + if (invitation[@"callToActionText"]) { + [inviteDialog setCallToActionText:invitation[@"callToActionText"]]; + } + if (invitation[@"customImage"]) { + [inviteDialog setCustomImage:invitation[@"customImage"]]; + } + if (invitation[@"deepLink"]) { + [inviteDialog setDeepLink:invitation[@"deepLink"]]; + } + + // Save the promise details for later + _invitationsRejecter = reject; + _invitationsResolver = resolve; + + // Open the invitation dialog + 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 && receivedInvite.inviteId) { + [RNFirebaseUtil sendJSEvent:self name:INVITES_INVITATION_RECEIVED body:@{ + @"deepLink": receivedInvite.deepLink, + @"invitationId": receivedInvite.inviteId, + }]; + } else { + [[RNFirebaseLinks instance] sendLink:receivedInvite.deepLink]; + } + }]; +} + + +- (NSArray *)supportedEvents { + return @[INVITES_INVITATION_RECEIVED]; +} + ++ (BOOL)requiresMainQueueSetup +{ + return YES; +} + +@end + +#else +@implementation RNFirebaseInvites +@end +#endif + diff --git a/ios/RNFirebase/links/RNFirebaseLinks.h b/ios/RNFirebase/links/RNFirebaseLinks.h index ac96b7e6..f2b68445 100644 --- a/ios/RNFirebase/links/RNFirebaseLinks.h +++ b/ios/RNFirebase/links/RNFirebaseLinks.h @@ -7,21 +7,13 @@ #import #import -@interface RNFirebaseLinks : RCTEventEmitter { - -} -+ (BOOL)application:(UIApplication *)app - openURL:(NSURL *)url - options:(NSDictionary *)options; +@interface RNFirebaseLinks : RCTEventEmitter -+ (BOOL)application:(UIApplication *)application - openURL:(NSURL *)url - sourceApplication:(NSString *)sourceApplication - annotation:(id)annotation; ++ (_Nonnull instancetype)instance; -+ (BOOL)application:(UIApplication *)application -continueUserActivity:(NSUserActivity *)userActivity - restorationHandler:(void (^)(NSArray *))restorationHandler; +- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options; +- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler; +- (void)sendLink:(NSString *)link; @end @@ -31,3 +23,4 @@ continueUserActivity:(NSUserActivity *)userActivity #endif #endif + diff --git a/ios/RNFirebase/links/RNFirebaseLinks.m b/ios/RNFirebase/links/RNFirebaseLinks.m index 0251e8d6..6c4d2f81 100644 --- a/ios/RNFirebase/links/RNFirebaseLinks.m +++ b/ios/RNFirebase/links/RNFirebaseLinks.m @@ -3,141 +3,78 @@ #if __has_include() #import #import "RNFirebaseEvents.h" - - -static void sendDynamicLink(NSURL *url, id sender) { - if (url) { - [[NSNotificationCenter defaultCenter] postNotificationName:LINKS_LINK_RECEIVED - object:sender - userInfo:@{@"url": url.absoluteString}]; - NSLog(@"sendDynamicLink Success: %@", url.absoluteString); - } -} +#import "RNFirebaseUtil.h" @implementation RNFirebaseLinks +static RNFirebaseLinks *theRNFirebaseLinks = nil; + ++ (nonnull instancetype)instance { + return theRNFirebaseLinks; +} + RCT_EXPORT_MODULE(); - (id)init { self = [super init]; if (self != nil) { NSLog(@"Setting up RNFirebaseLinks instance"); - [self initialiseLinks]; + // Set static instance for use from AppDelegate + theRNFirebaseLinks = self; } return self; } -- (void)initialiseLinks { - // Set up internal listener to send notification over bridge - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(sendDynamicLinkEvent:) - name:LINKS_LINK_RECEIVED - object:nil]; -} - - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } -+ (BOOL)application:(UIApplication *)app +// ******************************************************* +// ** Start AppDelegate methods +// ******************************************************* + +- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { - return [self handleLinkFromCustomSchemeURL:url]; -} - -+ (BOOL)application:(UIApplication *)application - openURL:(NSURL *)url - sourceApplication:(NSString *)sourceApplication - annotation:(id)annotation { - return [self handleLinkFromCustomSchemeURL:url]; -} - -+ (BOOL)handleLinkFromCustomSchemeURL:(NSURL *)url { - FIRDynamicLink *dynamicLink = - [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; + FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; if (dynamicLink && dynamicLink.url) { - NSURL* dynamicLinkUrl = dynamicLink.url; - sendDynamicLink(dynamicLinkUrl, self); + NSURL* url = dynamicLink.url; + [RNFirebaseUtil sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString]; return YES; } return NO; } -+ (BOOL)application:(UIApplication *)application +- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler { - BOOL handled = [[FIRDynamicLinks dynamicLinks] - handleUniversalLink:userActivity.webpageURL - completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) { - if (error != nil){ - NSLog(@"Failed to handle universal link: %@", [error localizedDescription]); - } - else { - if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { - NSURL* url = dynamicLink ? dynamicLink.url : userActivity.webpageURL; - sendDynamicLink(url, self); - } - } - }]; - return handled; -} - -- (NSArray *)supportedEvents { - return @[LINKS_LINK_RECEIVED]; -} - -- (void)sendDynamicLinkEvent:(NSNotification *)notification { - [self sendEventWithName:LINKS_LINK_RECEIVED body:notification.userInfo[@"url"]]; -} - --(void)handleInitialLinkFromCustomSchemeURL:(NSURL*)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject { - FIRDynamicLink *dynamicLink = - [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; - NSString* urlString = dynamicLink ? dynamicLink.url.absoluteString : (id)kCFNull; - NSLog(@"initial link is: %@", urlString); - resolve(urlString); -} - --(void)handleInitialLinkFromUniversalLinkURL:(NSDictionary *)userActivityDictionary resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject { - NSUserActivity* userActivity = (NSUserActivity*) userActivityDictionary[@"UIApplicationLaunchOptionsUserActivityKey"]; - if ([userActivityDictionary[UIApplicationLaunchOptionsUserActivityTypeKey] isEqual:NSUserActivityTypeBrowsingWeb]) - { - [[FIRDynamicLinks dynamicLinks] - handleUniversalLink:userActivity.webpageURL - completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) { - if (error != nil){ - NSLog(@"Failed to handle universal link: %@", [error localizedDescription]); - reject(@"links/failure", @"Failed to handle universal link", error); - } - else { - NSString* urlString = dynamicLink ? dynamicLink.url.absoluteString : userActivity.webpageURL.absoluteString; - NSLog(@"initial link is: %@", urlString); - resolve(urlString); - } - }]; - } - else { - NSLog(@"no initial link"); - resolve((id)kCFNull); - } -} - -RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) { - NSURL* url = (NSURL*)self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]; - [self handleInitialLinkFromCustomSchemeURL:url resolver:resolve rejecter:reject]; - - } else { - NSDictionary *userActivityDictionary = - self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]; - [self handleInitialLinkFromUniversalLinkURL:userActivityDictionary resolver:resolve rejecter:reject]; + if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { + return [[FIRDynamicLinks dynamicLinks] + handleUniversalLink:userActivity.webpageURL + completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) { + if (error != nil){ + NSLog(@"Failed to handle universal link: %@", [error localizedDescription]); + } else { + NSURL* url = dynamicLink ? dynamicLink.url : userActivity.webpageURL; + [RNFirebaseUtil sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString]; + } + }]; } + return NO; +} +// ******************************************************* +// ** Finish AppDelegate methods +// ******************************************************* + +- (void)sendLink:(NSString *)link { + [RNFirebaseUtil sendJSEvent:self name:LINKS_LINK_RECEIVED body:link]; } +// ** Start React Module methods ** RCT_EXPORT_METHOD(createDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { @try { FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata]; - + if (components == nil) { reject(@"links/failure", @"Failed to create Dynamic Link", nil); } else { @@ -176,16 +113,42 @@ RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RC } } +RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { + if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) { + NSURL* url = (NSURL*)self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]; + FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; + resolve(dynamicLink ? dynamicLink.url.absoluteString : nil); + } else if (self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey] + && [self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey][UIApplicationLaunchOptionsUserActivityTypeKey] isEqualToString:NSUserActivityTypeBrowsingWeb]) { + NSDictionary *dictionary = self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey]; + NSUserActivity* userActivity = (NSUserActivity*) dictionary[@"UIApplicationLaunchOptionsUserActivityKey"]; + [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL + completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) { + if (error != nil){ + NSLog(@"Failed to handle universal link: %@", [error localizedDescription]); + reject(@"links/failure", @"Failed to handle universal link", error); + } else { + NSString* urlString = dynamicLink ? dynamicLink.url.absoluteString : userActivity.webpageURL.absoluteString; + NSLog(@"initial link is: %@", urlString); + resolve(urlString); + } + }]; + } else { + resolve(nil); + } +} + +// ** Start internals ** - (FIRDynamicLinkComponents *)getDynamicLinkComponentsFromMetadata:(NSDictionary *)metadata { @try { NSURL *link = [NSURL URLWithString:metadata[@"link"]]; FIRDynamicLinkComponents *components = [FIRDynamicLinkComponents componentsWithLink:link domain:metadata[@"dynamicLinkDomain"]]; - + [self setAndroidParameters:metadata components:components]; [self setIosParameters:metadata components:components]; [self setSocialMetaTagParameters:metadata components:components]; - + return components; } @catch(NSException * e) { @@ -200,7 +163,7 @@ RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RC if (androidParametersDict) { FIRDynamicLinkAndroidParameters *androidParams = [FIRDynamicLinkAndroidParameters parametersWithPackageName: androidParametersDict[@"androidPackageName"]]; - + if (androidParametersDict[@"androidFallbackLink"]) { androidParams.fallbackURL = [NSURL URLWithString:androidParametersDict[@"androidFallbackLink"]]; } @@ -272,8 +235,11 @@ RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RC } } -+ (BOOL)requiresMainQueueSetup -{ +- (NSArray *)supportedEvents { + return @[LINKS_LINK_RECEIVED]; +} + ++ (BOOL)requiresMainQueueSetup { return YES; } diff --git a/lib/modules/invites/Invitation.js b/lib/modules/invites/Invitation.js index 66a82f61..04c0b0aa 100644 --- a/lib/modules/invites/Invitation.js +++ b/lib/modules/invites/Invitation.js @@ -24,6 +24,10 @@ export default class Invitation { this._title = title; } + get android(): AndroidInvitation { + return this._android; + } + /** * * @param androidClientId diff --git a/lib/modules/links/index.js b/lib/modules/links/index.js index 94770eed..95fb7566 100644 --- a/lib/modules/links/index.js +++ b/lib/modules/links/index.js @@ -10,11 +10,7 @@ import { getNativeModule } from '../../utils/native'; import type App from '../core/app'; -const EVENT_TYPE = { - Link: 'links_link_received', -}; - -const NATIVE_EVENTS = [EVENT_TYPE.Link]; +const NATIVE_EVENTS = ['links_link_received']; export const MODULE_NAME = 'RNFirebaseLinks'; export const NAMESPACE = 'links'; @@ -95,10 +91,6 @@ export default class Links extends ModuleBase { ); } - get EVENT_TYPE(): Object { - return EVENT_TYPE; - } - /** * Create long Dynamic Link from parameters * @param parameters @@ -154,6 +146,4 @@ export default class Links extends ModuleBase { } } -export const statics = { - EVENT_TYPE, -}; +export const statics = {}; diff --git a/tests/ios/ReactNativeFirebaseDemo/AppDelegate.m b/tests/ios/ReactNativeFirebaseDemo/AppDelegate.m index 81105040..478c7af9 100644 --- a/tests/ios/ReactNativeFirebaseDemo/AppDelegate.m +++ b/tests/ios/ReactNativeFirebaseDemo/AppDelegate.m @@ -11,14 +11,16 @@ #import #import -#import #import +@import Firebase; +@import GoogleSignIn; @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [FIRApp configure]; + [GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID; NSURL *jsCodeLocation; jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; diff --git a/tests/src/firebase.js b/tests/src/firebase.js index 5859017e..201b28c2 100644 --- a/tests/src/firebase.js +++ b/tests/src/firebase.js @@ -156,7 +156,7 @@ const instances = { web: firebase.initializeApp(config), native: RNfirebase, another: RNfirebase.initializeApp( - Platform.OS === 'ios' ? ios : android, + ios, // Platform.OS === 'ios' ? ios : android, 'anotherApp' ), };