Merge branch 'ios-invites'
This commit is contained in:
commit
526ea04853
|
@ -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
|
// Looks at the internals of the link data to detect whether it's an invitation or not
|
||||||
private boolean isInvitation(PendingDynamicLinkData pendingDynamicLinkData) {
|
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<String, Object> metaData) {
|
private DynamicLink.Builder getDynamicLinkBuilderFromMap(final Map<String, Object> metaData) {
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
839D91721EF3E20B0077C7C8 /* RNFirebaseCrash.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D915F1EF3E20A0077C7C8 /* RNFirebaseCrash.m */; };
|
839D91721EF3E20B0077C7C8 /* RNFirebaseCrash.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D915F1EF3E20A0077C7C8 /* RNFirebaseCrash.m */; };
|
||||||
839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */; };
|
839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */; };
|
||||||
839D91751EF3E20B0077C7C8 /* RNFirebasePerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.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 */; };
|
83C3EEEE1FA1EACC00B64D3C /* RNFirebaseUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 83C3EEEC1FA1EACC00B64D3C /* RNFirebaseUtil.m */; };
|
||||||
BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = BA84AE561FA9E59800E79390 /* RNFirebaseStorage.m */; };
|
BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = BA84AE561FA9E59800E79390 /* RNFirebaseStorage.m */; };
|
||||||
D950369E1D19C77400F7094D /* RNFirebase.m in Sources */ = {isa = PBXBuildFile; fileRef = D950369D1D19C77400F7094D /* RNFirebase.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 = "<group>"; };
|
839D91671EF3E20A0077C7C8 /* RNFirebasePerformance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebasePerformance.h; sourceTree = "<group>"; };
|
||||||
839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebasePerformance.m; sourceTree = "<group>"; };
|
839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebasePerformance.m; sourceTree = "<group>"; };
|
||||||
839D91771EF3E22F0077C7C8 /* RNFirebaseEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseEvents.h; path = RNFirebase/RNFirebaseEvents.h; sourceTree = "<group>"; };
|
839D91771EF3E22F0077C7C8 /* RNFirebaseEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseEvents.h; path = RNFirebase/RNFirebaseEvents.h; sourceTree = "<group>"; };
|
||||||
|
83AAA0772063DEC2007EC5F7 /* RNFirebaseInvites.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseInvites.m; sourceTree = "<group>"; };
|
||||||
|
83AAA0782063DEC2007EC5F7 /* RNFirebaseInvites.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseInvites.h; sourceTree = "<group>"; };
|
||||||
83C3EEEC1FA1EACC00B64D3C /* RNFirebaseUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNFirebaseUtil.m; path = RNFirebase/RNFirebaseUtil.m; sourceTree = "<group>"; };
|
83C3EEEC1FA1EACC00B64D3C /* RNFirebaseUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNFirebaseUtil.m; path = RNFirebase/RNFirebaseUtil.m; sourceTree = "<group>"; };
|
||||||
83C3EEED1FA1EACC00B64D3C /* RNFirebaseUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseUtil.h; path = RNFirebase/RNFirebaseUtil.h; sourceTree = "<group>"; };
|
83C3EEED1FA1EACC00B64D3C /* RNFirebaseUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseUtil.h; path = RNFirebase/RNFirebaseUtil.h; sourceTree = "<group>"; };
|
||||||
BA84AE551FA9E59800E79390 /* RNFirebaseStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseStorage.h; sourceTree = "<group>"; };
|
BA84AE551FA9E59800E79390 /* RNFirebaseStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseStorage.h; sourceTree = "<group>"; };
|
||||||
|
@ -133,6 +136,7 @@
|
||||||
58B511D21A9E6C8500147676 = {
|
58B511D21A9E6C8500147676 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
83AAA0762063DEC2007EC5F7 /* invites */,
|
||||||
838E372420231E15004DCD3A /* notifications */,
|
838E372420231E15004DCD3A /* notifications */,
|
||||||
838E372020231DF0004DCD3A /* instanceid */,
|
838E372020231DF0004DCD3A /* instanceid */,
|
||||||
8336930F1FD80DE800AA806B /* fabric */,
|
8336930F1FD80DE800AA806B /* fabric */,
|
||||||
|
@ -301,6 +305,16 @@
|
||||||
path = RNFirebase/perf;
|
path = RNFirebase/perf;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
83AAA0762063DEC2007EC5F7 /* invites */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
83AAA0772063DEC2007EC5F7 /* RNFirebaseInvites.m */,
|
||||||
|
83AAA0782063DEC2007EC5F7 /* RNFirebaseInvites.h */,
|
||||||
|
);
|
||||||
|
name = invites;
|
||||||
|
path = RNFirebase/invites;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
BA84AE541FA9E59800E79390 /* storage */ = {
|
BA84AE541FA9E59800E79390 /* storage */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -384,6 +398,7 @@
|
||||||
839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */,
|
839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */,
|
||||||
838E372720231E15004DCD3A /* RNFirebaseNotifications.m in Sources */,
|
838E372720231E15004DCD3A /* RNFirebaseNotifications.m in Sources */,
|
||||||
BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */,
|
BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */,
|
||||||
|
83AAA0792063DEC2007EC5F7 /* RNFirebaseInvites.m in Sources */,
|
||||||
8323CF071F6FBD870071420B /* NativeExpressComponent.m in Sources */,
|
8323CF071F6FBD870071420B /* NativeExpressComponent.m in Sources */,
|
||||||
83C3EEEE1FA1EACC00B64D3C /* RNFirebaseUtil.m in Sources */,
|
83C3EEEE1FA1EACC00B64D3C /* RNFirebaseUtil.m in Sources */,
|
||||||
839D91721EF3E20B0077C7C8 /* RNFirebaseCrash.m in Sources */,
|
839D91721EF3E20B0077C7C8 /* RNFirebaseCrash.m in Sources */,
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef RNFirebaseInvites_h
|
||||||
|
#define RNFirebaseInvites_h
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#if __has_include(<FirebaseInvites/FirebaseInvites.h>)
|
||||||
|
#import <FirebaseInvites/FirebaseInvites.h>
|
||||||
|
#import <React/RCTBridgeModule.h>
|
||||||
|
#import <React/RCTEventEmitter.h>
|
||||||
|
|
||||||
|
@interface RNFirebaseInvites : RCTEventEmitter<RCTBridgeModule, FIRInviteDelegate>
|
||||||
|
|
||||||
|
+ (_Nonnull instancetype)instance;
|
||||||
|
|
||||||
|
@property _Nullable RCTPromiseRejectBlock invitationsRejecter;
|
||||||
|
@property _Nullable RCTPromiseResolveBlock invitationsResolver;
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;
|
||||||
|
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#else
|
||||||
|
@interface RNFirebaseInvites : NSObject
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,186 @@
|
||||||
|
#import "RNFirebaseInvites.h"
|
||||||
|
|
||||||
|
#if __has_include(<FirebaseInvites/FirebaseInvites.h>)
|
||||||
|
#import "RNFirebaseEvents.h"
|
||||||
|
#import "RNFirebaseLinks.h"
|
||||||
|
#import "RNFirebaseUtil.h"
|
||||||
|
#import <FirebaseInvites/FirebaseInvites.h>
|
||||||
|
|
||||||
|
#import <React/RCTEventDispatcher.h>
|
||||||
|
#import <React/RCTConvert.h>
|
||||||
|
#import <React/RCTUtils.h>
|
||||||
|
|
||||||
|
@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<UIApplicationOpenURLOptionsKey,id> *)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<FIRInviteBuilder> 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<NSString *> *)supportedEvents {
|
||||||
|
return @[INVITES_INVITATION_RECEIVED];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (BOOL)requiresMainQueueSetup
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#else
|
||||||
|
@implementation RNFirebaseInvites
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
|
|
|
@ -7,21 +7,13 @@
|
||||||
#import <React/RCTBridgeModule.h>
|
#import <React/RCTBridgeModule.h>
|
||||||
#import <React/RCTEventEmitter.h>
|
#import <React/RCTEventEmitter.h>
|
||||||
|
|
||||||
@interface RNFirebaseLinks : RCTEventEmitter<RCTBridgeModule> {
|
@interface RNFirebaseLinks : RCTEventEmitter<RCTBridgeModule>
|
||||||
|
|
||||||
}
|
+ (_Nonnull instancetype)instance;
|
||||||
+ (BOOL)application:(UIApplication *)app
|
|
||||||
openURL:(NSURL *)url
|
|
||||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;
|
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *)application
|
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;
|
||||||
openURL:(NSURL *)url
|
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler;
|
||||||
sourceApplication:(NSString *)sourceApplication
|
- (void)sendLink:(NSString *)link;
|
||||||
annotation:(id)annotation;
|
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *)application
|
|
||||||
continueUserActivity:(NSUserActivity *)userActivity
|
|
||||||
restorationHandler:(void (^)(NSArray *))restorationHandler;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -31,3 +23,4 @@ continueUserActivity:(NSUserActivity *)userActivity
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -3,137 +3,74 @@
|
||||||
#if __has_include(<FirebaseDynamicLinks/FirebaseDynamicLinks.h>)
|
#if __has_include(<FirebaseDynamicLinks/FirebaseDynamicLinks.h>)
|
||||||
#import <Firebase.h>
|
#import <Firebase.h>
|
||||||
#import "RNFirebaseEvents.h"
|
#import "RNFirebaseEvents.h"
|
||||||
|
#import "RNFirebaseUtil.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@implementation RNFirebaseLinks
|
@implementation RNFirebaseLinks
|
||||||
|
|
||||||
|
static RNFirebaseLinks *theRNFirebaseLinks = nil;
|
||||||
|
|
||||||
|
+ (nonnull instancetype)instance {
|
||||||
|
return theRNFirebaseLinks;
|
||||||
|
}
|
||||||
|
|
||||||
RCT_EXPORT_MODULE();
|
RCT_EXPORT_MODULE();
|
||||||
|
|
||||||
- (id)init {
|
- (id)init {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self != nil) {
|
if (self != nil) {
|
||||||
NSLog(@"Setting up RNFirebaseLinks instance");
|
NSLog(@"Setting up RNFirebaseLinks instance");
|
||||||
[self initialiseLinks];
|
// Set static instance for use from AppDelegate
|
||||||
|
theRNFirebaseLinks = self;
|
||||||
}
|
}
|
||||||
return 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 {
|
- (void)dealloc {
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *)app
|
// *******************************************************
|
||||||
|
// ** Start AppDelegate methods
|
||||||
|
// *******************************************************
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)app
|
||||||
openURL:(NSURL *)url
|
openURL:(NSURL *)url
|
||||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||||
return [self handleLinkFromCustomSchemeURL:url];
|
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL: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];
|
|
||||||
if (dynamicLink && dynamicLink.url) {
|
if (dynamicLink && dynamicLink.url) {
|
||||||
NSURL* dynamicLinkUrl = dynamicLink.url;
|
NSURL* url = dynamicLink.url;
|
||||||
sendDynamicLink(dynamicLinkUrl, self);
|
[RNFirebaseUtil sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString];
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *)application
|
- (BOOL)application:(UIApplication *)application
|
||||||
continueUserActivity:(NSUserActivity *)userActivity
|
continueUserActivity:(NSUserActivity *)userActivity
|
||||||
restorationHandler:(void (^)(NSArray *))restorationHandler {
|
restorationHandler:(void (^)(NSArray *))restorationHandler {
|
||||||
BOOL handled = [[FIRDynamicLinks dynamicLinks]
|
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
|
||||||
handleUniversalLink:userActivity.webpageURL
|
return [[FIRDynamicLinks dynamicLinks]
|
||||||
completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) {
|
handleUniversalLink:userActivity.webpageURL
|
||||||
if (error != nil){
|
completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) {
|
||||||
NSLog(@"Failed to handle universal link: %@", [error localizedDescription]);
|
if (error != nil){
|
||||||
}
|
NSLog(@"Failed to handle universal link: %@", [error localizedDescription]);
|
||||||
else {
|
} else {
|
||||||
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
|
NSURL* url = dynamicLink ? dynamicLink.url : userActivity.webpageURL;
|
||||||
NSURL* url = dynamicLink ? dynamicLink.url : userActivity.webpageURL;
|
[RNFirebaseUtil sendJSEvent:self name:LINKS_LINK_RECEIVED body:url.absoluteString];
|
||||||
sendDynamicLink(url, self);
|
}
|
||||||
}
|
}];
|
||||||
}
|
|
||||||
}];
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray<NSString *> *)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];
|
|
||||||
}
|
}
|
||||||
|
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) {
|
RCT_EXPORT_METHOD(createDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||||
@try {
|
@try {
|
||||||
FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata];
|
FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata];
|
||||||
|
@ -176,6 +113,32 @@ 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 {
|
- (FIRDynamicLinkComponents *)getDynamicLinkComponentsFromMetadata:(NSDictionary *)metadata {
|
||||||
@try {
|
@try {
|
||||||
NSURL *link = [NSURL URLWithString:metadata[@"link"]];
|
NSURL *link = [NSURL URLWithString:metadata[@"link"]];
|
||||||
|
@ -272,8 +235,11 @@ RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)requiresMainQueueSetup
|
- (NSArray<NSString *> *)supportedEvents {
|
||||||
{
|
return @[LINKS_LINK_RECEIVED];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (BOOL)requiresMainQueueSetup {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@ export default class Invitation {
|
||||||
this._title = title;
|
this._title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get android(): AndroidInvitation {
|
||||||
|
return this._android;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param androidClientId
|
* @param androidClientId
|
||||||
|
|
|
@ -10,11 +10,7 @@ import { getNativeModule } from '../../utils/native';
|
||||||
|
|
||||||
import type App from '../core/app';
|
import type App from '../core/app';
|
||||||
|
|
||||||
const EVENT_TYPE = {
|
const NATIVE_EVENTS = ['links_link_received'];
|
||||||
Link: 'links_link_received',
|
|
||||||
};
|
|
||||||
|
|
||||||
const NATIVE_EVENTS = [EVENT_TYPE.Link];
|
|
||||||
|
|
||||||
export const MODULE_NAME = 'RNFirebaseLinks';
|
export const MODULE_NAME = 'RNFirebaseLinks';
|
||||||
export const NAMESPACE = 'links';
|
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
|
* Create long Dynamic Link from parameters
|
||||||
* @param parameters
|
* @param parameters
|
||||||
|
@ -154,6 +146,4 @@ export default class Links extends ModuleBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const statics = {
|
export const statics = {};
|
||||||
EVENT_TYPE,
|
|
||||||
};
|
|
||||||
|
|
|
@ -11,14 +11,16 @@
|
||||||
|
|
||||||
#import <React/RCTBundleURLProvider.h>
|
#import <React/RCTBundleURLProvider.h>
|
||||||
#import <React/RCTRootView.h>
|
#import <React/RCTRootView.h>
|
||||||
#import <Firebase.h>
|
|
||||||
#import <RNFirebaseNotifications.h>
|
#import <RNFirebaseNotifications.h>
|
||||||
|
@import Firebase;
|
||||||
|
@import GoogleSignIn;
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
{
|
{
|
||||||
[FIRApp configure];
|
[FIRApp configure];
|
||||||
|
[GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID;
|
||||||
|
|
||||||
NSURL *jsCodeLocation;
|
NSURL *jsCodeLocation;
|
||||||
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
|
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
|
||||||
|
|
|
@ -156,7 +156,7 @@ const instances = {
|
||||||
web: firebase.initializeApp(config),
|
web: firebase.initializeApp(config),
|
||||||
native: RNfirebase,
|
native: RNfirebase,
|
||||||
another: RNfirebase.initializeApp(
|
another: RNfirebase.initializeApp(
|
||||||
Platform.OS === 'ios' ? ios : android,
|
ios, // Platform.OS === 'ios' ? ios : android,
|
||||||
'anotherApp'
|
'anotherApp'
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue