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..ddeda5ac --- /dev/null +++ b/ios/RNFirebase/invites/RNFirebaseInvites.h @@ -0,0 +1,29 @@ +#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; + +#if !TARGET_OS_TV +- (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo; +- (void)didRegisterUserNotificationSettings:(nonnull UIUserNotificationSettings *)notificationSettings; +#endif + +@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..2d064436 --- /dev/null +++ b/ios/RNFirebase/invites/RNFirebaseInvites.m @@ -0,0 +1,133 @@ +#import "RNFirebaseInvites.h" + +#if __has_include() +#import "RNFirebaseEvents.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 +// ******************************************************* + +// Listen for permission response +- (void) didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { + +} + +// Listen for FCM data messages that arrive as a remote notification +- (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo { + +} + +// ******************************************************* +// ** Finish AppDelegate methods +// ******************************************************* + + +// ******************************************************* +// ** Start FIRInviteDelegate methods +// ******************************************************* + +// 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); + } else { + _invitationsResolver(invitationIds); + } + _invitationsRejecter = nil; + _invitationsResolver = nil; +} + +// ******************************************************* +// ** Finish FIRInviteDelegate methods +// ******************************************************* + +// ** Start React Module methods ** +RCT_EXPORT_METHOD(getInitialInvitation:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { + // TODO + 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 + [inviteDialog open]; +} + +// ** Start internals ** + +- (NSArray *)supportedEvents { + return @[INVITES_INVITATION_RECEIVED]; +} + ++ (BOOL)requiresMainQueueSetup +{ + return YES; +} + +@end + +#else +@implementation RNFirebaseInvites +@end +#endif 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' ), };