[links] Refactor links to use builder classes

This commit is contained in:
Chris Bianca 2018-03-23 13:24:31 +00:00
parent 526ea04853
commit 7f90e485c8
14 changed files with 766 additions and 228 deletions

View File

@ -6,8 +6,6 @@ import android.net.Uri;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.util.Log; import android.util.Log;
import java.util.Map;
import com.facebook.react.bridge.ActivityEventListener; import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.Promise;
@ -16,7 +14,6 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.google.firebase.appinvite.FirebaseAppInvite; import com.google.firebase.appinvite.FirebaseAppInvite;
import com.google.firebase.dynamiclinks.DynamicLink; import com.google.firebase.dynamiclinks.DynamicLink;
import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
@ -47,15 +44,12 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
} }
@ReactMethod @ReactMethod
public void createDynamicLink(final ReadableMap parameters, final Promise promise) { public void createDynamicLink(final ReadableMap linkData, final Promise promise) {
try { try {
Map<String, Object> metaData = Utils.recursivelyDeconstructReadableMap(parameters); DynamicLink.Builder builder = getDynamicLinkBuilder(linkData);
String link = builder.buildDynamicLink().getUri().toString();
DynamicLink.Builder builder = getDynamicLinkBuilderFromMap(metaData); Log.d(TAG, "created dynamic link: " + link);
Uri link = builder.buildDynamicLink().getUri(); promise.resolve(link);
Log.d(TAG, "created dynamic link: " + link.toString());
promise.resolve(link.toString());
} catch (Exception ex) { } catch (Exception ex) {
Log.e(TAG, "create dynamic link failure " + ex.getMessage()); Log.e(TAG, "create dynamic link failure " + ex.getMessage());
promise.reject("links/failure", ex.getMessage(), ex); promise.reject("links/failure", ex.getMessage(), ex);
@ -63,26 +57,31 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
} }
@ReactMethod @ReactMethod
public void createShortDynamicLink(final ReadableMap parameters, final Promise promise) { public void createShortDynamicLink(final ReadableMap linkData, final String type, final Promise promise) {
try { try {
Map<String, Object> metaData = Utils.recursivelyDeconstructReadableMap(parameters); DynamicLink.Builder builder = getDynamicLinkBuilder(linkData);
Task<ShortDynamicLink> shortLinkTask;
if ("SHORT".equals(type)) {
shortLinkTask = builder.buildShortDynamicLink(ShortDynamicLink.Suffix.SHORT);
} else if ("UNGUESSABLE".equals(type)) {
shortLinkTask = builder.buildShortDynamicLink(ShortDynamicLink.Suffix.UNGUESSABLE);
} else {
shortLinkTask = builder.buildShortDynamicLink();
}
DynamicLink.Builder builder = getDynamicLinkBuilderFromMap(metaData); shortLinkTask.addOnCompleteListener(new OnCompleteListener<ShortDynamicLink>() {
Task<ShortDynamicLink> shortLinkTask = getShortDynamicLinkTask(builder, metaData)
.addOnCompleteListener(new OnCompleteListener<ShortDynamicLink>() {
@Override @Override
public void onComplete(@NonNull Task<ShortDynamicLink> task) { public void onComplete(@NonNull Task<ShortDynamicLink> task) {
if (task.isSuccessful()) { if (task.isSuccessful()) {
Uri shortLink = task.getResult().getShortLink(); String shortLink = task.getResult().getShortLink().toString();
Log.d(TAG, "created short dynamic link: " + shortLink.toString()); Log.d(TAG, "created short dynamic link: " + shortLink);
promise.resolve(shortLink.toString()); promise.resolve(shortLink);
} else { } else {
Log.e(TAG, "create short dynamic link failure " + task.getException().getMessage()); Log.e(TAG, "create short dynamic link failure " + task.getException().getMessage());
promise.reject("links/failure", task.getException().getMessage(), task.getException()); promise.reject("links/failure", task.getException().getMessage(), task.getException());
} }
} }
}); });
} catch (Exception ex) { } catch (Exception ex) {
Log.e(TAG, "create short dynamic link failure " + ex.getMessage()); Log.e(TAG, "create short dynamic link failure " + ex.getMessage());
promise.reject("links/failure", ex.getMessage(), ex); promise.reject("links/failure", ex.getMessage(), ex);
@ -178,95 +177,122 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
return FirebaseAppInvite.getInvitation(pendingDynamicLinkData) != null; return FirebaseAppInvite.getInvitation(pendingDynamicLinkData) != null;
} }
private DynamicLink.Builder getDynamicLinkBuilderFromMap(final Map<String, Object> metaData) { private DynamicLink.Builder getDynamicLinkBuilder(final ReadableMap linkData) {
DynamicLink.Builder parametersBuilder = FirebaseDynamicLinks.getInstance().createDynamicLink(); DynamicLink.Builder builder = FirebaseDynamicLinks.getInstance().createDynamicLink();
try { try {
parametersBuilder.setLink(Uri.parse((String) metaData.get("link"))); builder.setLink(Uri.parse(linkData.getString("link")));
parametersBuilder.setDynamicLinkDomain((String) metaData.get("dynamicLinkDomain")); builder.setDynamicLinkDomain(linkData.getString("dynamicLinkDomain"));
setAndroidParameters(metaData, parametersBuilder); setAnalyticsParameters(linkData.getMap("analytics"), builder);
setIosParameters(metaData, parametersBuilder); setAndroidParameters(linkData.getMap("android"), builder);
setSocialMetaTagParameters(metaData, parametersBuilder); setIosParameters(linkData.getMap("ios"), builder);
setITunesParameters(linkData.getMap("itunes"), builder);
setNavigationParameters(linkData.getMap("navigation"), builder);
setSocialParameters(linkData.getMap("social"), builder);
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "error while building parameters " + e.getMessage()); Log.e(TAG, "error while building parameters " + e.getMessage());
throw e; throw e;
} }
return parametersBuilder; return builder;
} }
private Task<ShortDynamicLink> getShortDynamicLinkTask(final DynamicLink.Builder builder, final Map<String, Object> metaData) { private void setAnalyticsParameters(final ReadableMap analyticsData, final DynamicLink.Builder builder) {
Map<String, Object> suffix = (Map<String, Object>) metaData.get("suffix"); DynamicLink.GoogleAnalyticsParameters.Builder analyticsParameters = new DynamicLink.GoogleAnalyticsParameters.Builder();
if (suffix != null) {
String option = (String) suffix.get("option"); if (analyticsData.hasKey("campaign")) {
if ("SHORT".equals(option)) { analyticsParameters.setCampaign(analyticsData.getString("campaign"));
return builder.buildShortDynamicLink(ShortDynamicLink.Suffix.SHORT);
} else if ("UNGUESSABLE".equals(option)) {
return builder.buildShortDynamicLink(ShortDynamicLink.Suffix.UNGUESSABLE);
}
} }
return builder.buildShortDynamicLink(); if (analyticsData.hasKey("content")) {
analyticsParameters.setContent(analyticsData.getString("content"));
}
if (analyticsData.hasKey("medium")) {
analyticsParameters.setMedium(analyticsData.getString("medium"));
}
if (analyticsData.hasKey("source")) {
analyticsParameters.setSource(analyticsData.getString("source"));
}
if (analyticsData.hasKey("term")) {
analyticsParameters.setTerm(analyticsData.getString("term"));
}
builder.setGoogleAnalyticsParameters(analyticsParameters.build());
} }
private void setAndroidParameters(final ReadableMap androidData, final DynamicLink.Builder builder) {
if (androidData.hasKey("packageName")) {
DynamicLink.AndroidParameters.Builder androidParameters = new DynamicLink.AndroidParameters.Builder(androidData.getString("packageName"));
private void setAndroidParameters(final Map<String, Object> metaData, final DynamicLink.Builder parametersBuilder) { if (androidData.hasKey("fallbackUrl")) {
Map<String, Object> androidParameters = (Map<String, Object>) metaData.get("androidInfo"); androidParameters.setFallbackUrl(Uri.parse(androidData.getString("fallbackUrl")));
if (androidParameters != null) {
DynamicLink.AndroidParameters.Builder androidParametersBuilder =
new DynamicLink.AndroidParameters.Builder((String) androidParameters.get("androidPackageName"));
if (androidParameters.containsKey("androidFallbackLink")) {
androidParametersBuilder.setFallbackUrl(Uri.parse((String) androidParameters.get("androidFallbackLink")));
} }
if (androidParameters.containsKey("androidMinPackageVersionCode")) { if (androidData.hasKey("minimumVersion")) {
androidParametersBuilder.setMinimumVersion(Integer.parseInt((String) androidParameters.get("androidMinPackageVersionCode"))); androidParameters.setMinimumVersion(Integer.parseInt(androidData.getString("minimumVersion")));
} }
parametersBuilder.setAndroidParameters(androidParametersBuilder.build()); builder.setAndroidParameters(androidParameters.build());
} }
} }
private void setIosParameters(final Map<String, Object> metaData, final DynamicLink.Builder parametersBuilder) { private void setIosParameters(final ReadableMap iosData, final DynamicLink.Builder builder) {
Map<String, Object> iosParameters = (Map<String, Object>) metaData.get("iosInfo"); if (iosData.hasKey("bundleId")) {
if (iosParameters != null) { DynamicLink.IosParameters.Builder iosParameters =
DynamicLink.IosParameters.Builder iosParametersBuilder = new DynamicLink.IosParameters.Builder(iosData.getString("bundleId"));
new DynamicLink.IosParameters.Builder((String) iosParameters.get("iosBundleId"));
if (iosParameters.containsKey("iosAppStoreId")) { if (iosData.hasKey("appStoreId")) {
iosParametersBuilder.setAppStoreId((String) iosParameters.get("iosAppStoreId")); iosParameters.setAppStoreId(iosData.getString("appStoreId"));
} }
if (iosParameters.containsKey("iosCustomScheme")) { if (iosData.hasKey("customScheme")) {
iosParametersBuilder.setCustomScheme((String) iosParameters.get("iosCustomScheme")); iosParameters.setCustomScheme(iosData.getString("customScheme"));
} }
if (iosParameters.containsKey("iosFallbackLink")) { if (iosData.hasKey("fallbackUrl")) {
iosParametersBuilder.setFallbackUrl(Uri.parse((String) iosParameters.get("iosFallbackLink"))); iosParameters.setFallbackUrl(Uri.parse(iosData.getString("fallbackUrl")));
} }
if (iosParameters.containsKey("iosIpadBundleId")) { if (iosData.hasKey("iPadBundleId")) {
iosParametersBuilder.setIpadBundleId((String) iosParameters.get("iosIpadBundleId")); iosParameters.setIpadBundleId(iosData.getString("iPadBundleId"));
} }
if (iosParameters.containsKey("iosIpadFallbackLink")) { if (iosData.hasKey("iPadFallbackUrl")) {
iosParametersBuilder.setIpadFallbackUrl(Uri.parse((String) iosParameters.get("iosIpadFallbackLink"))); iosParameters.setIpadFallbackUrl(Uri.parse(iosData.getString("iPadFallbackUrl")));
} }
if (iosParameters.containsKey("iosMinPackageVersionCode")) { if (iosData.hasKey("minimumVersion")) {
iosParametersBuilder.setMinimumVersion((String) iosParameters.get("iosMinPackageVersionCode")); iosParameters.setMinimumVersion(iosData.getString("minimumVersion"));
} }
parametersBuilder.setIosParameters(iosParametersBuilder.build()); builder.setIosParameters(iosParameters.build());
} }
} }
private void setSocialMetaTagParameters(final Map<String, Object> metaData, final DynamicLink.Builder parametersBuilder) { private void setITunesParameters(final ReadableMap itunesData, final DynamicLink.Builder builder) {
Map<String, Object> socialMetaTagParameters = (Map<String, Object>) metaData.get("socialMetaTagInfo"); DynamicLink.ItunesConnectAnalyticsParameters.Builder itunesParameters = new DynamicLink.ItunesConnectAnalyticsParameters.Builder();
if (socialMetaTagParameters != null) {
DynamicLink.SocialMetaTagParameters.Builder socialMetaTagParametersBuilder =
new DynamicLink.SocialMetaTagParameters.Builder();
if (socialMetaTagParameters.containsKey("socialDescription")) { if (itunesData.hasKey("affiliateToken")) {
socialMetaTagParametersBuilder.setDescription((String) socialMetaTagParameters.get("socialDescription")); itunesParameters.setAffiliateToken(itunesData.getString("affiliateToken"));
}
if (socialMetaTagParameters.containsKey("socialImageLink")) {
socialMetaTagParametersBuilder.setImageUrl(Uri.parse((String) socialMetaTagParameters.get("socialImageLink")));
}
if (socialMetaTagParameters.containsKey("socialTitle")) {
socialMetaTagParametersBuilder.setTitle((String) socialMetaTagParameters.get("socialTitle"));
}
parametersBuilder.setSocialMetaTagParameters(socialMetaTagParametersBuilder.build());
} }
if (itunesData.hasKey("campaignToken")) {
itunesParameters.setCampaignToken(itunesData.getString("campaignToken"));
}
if (itunesData.hasKey("providerToken")) {
itunesParameters.setProviderToken(itunesData.getString("providerToken"));
}
builder.setItunesConnectAnalyticsParameters(itunesParameters.build());
}
private void setNavigationParameters(final ReadableMap navigationData, final DynamicLink.Builder builder) {
DynamicLink.NavigationInfoParameters.Builder navigationParameters = new DynamicLink.NavigationInfoParameters.Builder();
if (navigationData.hasKey("forcedRedirectEnabled")) {
navigationParameters.setForcedRedirectEnabled(navigationData.getBoolean("forcedRedirectEnabled"));
}
builder.setNavigationInfoParameters(navigationParameters.build());
}
private void setSocialParameters(final ReadableMap socialData, final DynamicLink.Builder builder) {
DynamicLink.SocialMetaTagParameters.Builder socialParameters = new DynamicLink.SocialMetaTagParameters.Builder();
if (socialData.hasKey("descriptionText")) {
socialParameters.setDescription(socialData.getString("descriptionText"));
}
if (socialData.hasKey("imageUrl")) {
socialParameters.setImageUrl(Uri.parse(socialData.getString("imageUrl")));
}
if (socialData.hasKey("title")) {
socialParameters.setTitle(socialData.getString("title"));
}
builder.setSocialMetaTagParameters(socialParameters.build());
} }
} }

View File

@ -71,16 +71,18 @@ continueUserActivity:(NSUserActivity *)userActivity
} }
// ** Start React Module methods ** // ** Start React Module methods **
RCT_EXPORT_METHOD(createDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { RCT_EXPORT_METHOD(createDynamicLink:(NSDictionary *)linkData
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
@try { @try {
FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata]; FIRDynamicLinkComponents *dynamicLink = [self buildDynamicLink:linkData];
if (components == nil) { if (dynamicLink == nil) {
reject(@"links/failure", @"Failed to create Dynamic Link", nil); reject(@"links/failure", @"Failed to create Dynamic Link", nil);
} else { } else {
NSURL *longLink = components.url; NSString *longLink = dynamicLink.url.absoluteString;
NSLog(@"created long dynamic link: %@", longLink.absoluteString); NSLog(@"created long dynamic link: %@", longLink);
resolve(longLink.absoluteString); resolve(longLink);
} }
} }
@catch(NSException * e) { @catch(NSException * e) {
@ -89,21 +91,29 @@ RCT_EXPORT_METHOD(createDynamicLink: (NSDictionary *) metadata resolver:(RCTProm
} }
} }
RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { RCT_EXPORT_METHOD(createShortDynamicLink:(NSDictionary *)linkData
type:(NSString *)type
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
@try { @try {
FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata]; FIRDynamicLinkComponents *components = [self buildDynamicLink:linkData];
[self setSuffixParameters:metadata components:components]; if (type) {
[components shortenWithCompletion:^(NSURL *_Nullable shortURL, FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options];
NSArray *_Nullable warnings, if ([type isEqual: @"SHORT"]) {
NSError *_Nullable error) { options.pathLength = FIRShortDynamicLinkPathLengthShort;
} else if ([type isEqual: @"UNGUESSABLE"]) {
options.pathLength = FIRShortDynamicLinkPathLengthUnguessable;
}
components.options = options;
}
[components shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, NSError *_Nullable error) {
if (error) { if (error) {
NSLog(@"create short dynamic link failure %@", [error localizedDescription]); NSLog(@"create short dynamic link failure %@", [error localizedDescription]);
reject(@"links/failure", @"Failed to create Short Dynamic Link", error); reject(@"links/failure", @"Failed to create Short Dynamic Link", error);
} } else {
else { NSString *shortLink = shortURL.absoluteString;
NSURL *shortLink = shortURL; NSLog(@"created short dynamic link: %@", shortLink);
NSLog(@"created short dynamic link: %@", shortLink.absoluteString); resolve(shortLink);
resolve(shortLink.absoluteString);
} }
}]; }];
} }
@ -139,15 +149,17 @@ RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPr
} }
// ** Start internals ** // ** Start internals **
- (FIRDynamicLinkComponents *)getDynamicLinkComponentsFromMetadata:(NSDictionary *)metadata { - (FIRDynamicLinkComponents *)buildDynamicLink:(NSDictionary *)linkData {
@try { @try {
NSURL *link = [NSURL URLWithString:metadata[@"link"]]; NSURL *link = [NSURL URLWithString:linkData[@"link"]];
FIRDynamicLinkComponents *components = FIRDynamicLinkComponents *components = [FIRDynamicLinkComponents componentsWithLink:link domain:linkData[@"dynamicLinkDomain"]];
[FIRDynamicLinkComponents componentsWithLink:link domain:metadata[@"dynamicLinkDomain"]];
[self setAndroidParameters:metadata components:components]; [self setAnalyticsParameters:linkData[@"analytics"] components:components];
[self setIosParameters:metadata components:components]; [self setAndroidParameters:linkData[@"android"] components:components];
[self setSocialMetaTagParameters:metadata components:components]; [self setIosParameters:linkData[@"ios"] components:components];
[self setITunesParameters:linkData[@"itunes"] components:components];
[self setNavigationParameters:linkData[@"navigation"] components:components];
[self setSocialParameters:linkData[@"social"] components:components];
return components; return components;
} }
@ -157,82 +169,106 @@ RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPr
} }
} }
- (void)setAndroidParameters:(NSDictionary *)metadata - (void)setAnalyticsParameters:(NSDictionary *)analyticsData
components:(FIRDynamicLinkComponents *)components {
FIRDynamicLinkGoogleAnalyticsParameters *analyticsParams = [FIRDynamicLinkGoogleAnalyticsParameters parameters];
if (analyticsData[@"campaign"]) {
analyticsParams.campaign = analyticsData[@"campaign"];
}
if (analyticsData[@"content"]) {
analyticsParams.content = analyticsData[@"content"];
}
if (analyticsData[@"medium"]) {
analyticsParams.medium = analyticsData[@"medium"];
}
if (analyticsData[@"source"]) {
analyticsParams.source = analyticsData[@"source"];
}
if (analyticsData[@"term"]) {
analyticsParams.term = analyticsData[@"term"];
}
components.analyticsParameters = analyticsParams;
}
- (void)setAndroidParameters:(NSDictionary *)androidData
components:(FIRDynamicLinkComponents *)components { components:(FIRDynamicLinkComponents *)components {
NSDictionary *androidParametersDict = metadata[@"androidInfo"]; if (androidData[@"packageName"]) {
if (androidParametersDict) { FIRDynamicLinkAndroidParameters *androidParams = [FIRDynamicLinkAndroidParameters parametersWithPackageName: androidData[@"packageName"]];
FIRDynamicLinkAndroidParameters *androidParams = [FIRDynamicLinkAndroidParameters
parametersWithPackageName: androidParametersDict[@"androidPackageName"]];
if (androidParametersDict[@"androidFallbackLink"]) { if (androidData[@"fallbackUrl"]) {
androidParams.fallbackURL = [NSURL URLWithString:androidParametersDict[@"androidFallbackLink"]]; androidParams.fallbackURL = [NSURL URLWithString:androidData[@"fallbackUrl"]];
} }
if (androidParametersDict[@"androidMinPackageVersionCode"]) { if (androidData[@"minimumVersion"]) {
androidParams.minimumVersion = [androidParametersDict[@"androidMinPackageVersionCode"] integerValue]; androidParams.minimumVersion = [androidData[@"minimumVersion"] integerValue];
} }
components.androidParameters = androidParams; components.androidParameters = androidParams;
} }
} }
- (void)setIosParameters:(NSDictionary *)metadata - (void)setIosParameters:(NSDictionary *)iosData
components:(FIRDynamicLinkComponents *)components { components:(FIRDynamicLinkComponents *)components {
NSDictionary *iosParametersDict = metadata[@"iosInfo"]; if (iosData[@"bundleId"]) {
if (iosParametersDict) { FIRDynamicLinkIOSParameters *iOSParams = [FIRDynamicLinkIOSParameters parametersWithBundleID:iosData[@"bundleId"]];
FIRDynamicLinkIOSParameters *iOSParams = [FIRDynamicLinkIOSParameters if (iosData[@"appStoreId"]) {
parametersWithBundleID:iosParametersDict[@"iosBundleId"]]; iOSParams.appStoreID = iosData[@"appStoreId"];
if (iosParametersDict[@"iosAppStoreId"]) {
iOSParams.appStoreID = iosParametersDict[@"iosAppStoreId"];
} }
if (iosParametersDict[@"iosCustomScheme"]) { if (iosData[@"customScheme"]) {
iOSParams.customScheme = iosParametersDict[@"iosCustomScheme"]; iOSParams.customScheme = iosData[@"customScheme"];
} }
if (iosParametersDict[@"iosFallbackLink"]) { if (iosData[@"fallbackUrl"]) {
iOSParams.fallbackURL = [NSURL URLWithString:iosParametersDict[@"iosFallbackLink"]]; iOSParams.fallbackURL = [NSURL URLWithString:iosData[@"fallbackUrl"]];
} }
if (iosParametersDict[@"iosIpadBundleId"]) { if (iosData[@"iPadBundleId"]) {
iOSParams.iPadBundleID = iosParametersDict[@"iosIpadBundleId"]; iOSParams.iPadBundleID = iosData[@"iPadBundleId"];
} }
if (iosParametersDict[@"iosIpadFallbackLink"]) { if (iosData[@"iPadFallbackUrl"]) {
iOSParams.iPadFallbackURL = [NSURL URLWithString:iosParametersDict[@"iosIpadFallbackLink"]]; iOSParams.iPadFallbackURL = [NSURL URLWithString:iosData[@"iPadFallbackUrl"]];
} }
if (iosParametersDict[@"iosMinPackageVersionCode"]) { if (iosData[@"minimumVersion"]) {
iOSParams.minimumAppVersion = iosParametersDict[@"iosMinPackageVersionCode"]; iOSParams.minimumAppVersion = iosData[@"minimumVersion"];
} }
components.iOSParameters = iOSParams; components.iOSParameters = iOSParams;
} }
} }
- (void)setSocialMetaTagParameters:(NSDictionary *)metadata - (void)setITunesParameters:(NSDictionary *)itunesData
components:(FIRDynamicLinkComponents *)components { components:(FIRDynamicLinkComponents *)components {
NSDictionary *socialParamsDict = metadata[@"socialMetaTagInfo"]; FIRDynamicLinkItunesConnectAnalyticsParameters *itunesParams = [FIRDynamicLinkItunesConnectAnalyticsParameters parameters];
if (socialParamsDict) { if (itunesData[@"affiliateToken"]) {
FIRDynamicLinkSocialMetaTagParameters *socialParams = [FIRDynamicLinkSocialMetaTagParameters parameters]; itunesParams.affiliateToken = itunesData[@"affiliateToken"];
if (socialParamsDict[@"socialTitle"]) {
socialParams.title = socialParamsDict[@"socialTitle"];
}
if (socialParamsDict[@"socialDescription"]) {
socialParams.descriptionText = socialParamsDict[@"socialDescription"];
}
if (socialParamsDict[@"socialImageLink"]) {
socialParams.imageURL = [NSURL URLWithString:socialParamsDict[@"socialImageLink"]];
}
components.socialMetaTagParameters = socialParams;
} }
if (itunesData[@"campaignToken"]) {
itunesParams.campaignToken = itunesData[@"campaignToken"];
}
if (itunesData[@"providerToken"]) {
itunesParams.providerToken = itunesData[@"providerToken"];
}
components.iTunesConnectParameters = itunesParams;
} }
- (void)setSuffixParameters:(NSDictionary *)metadata - (void)setNavigationParameters:(NSDictionary *)navigationData
components:(FIRDynamicLinkComponents *)components { components:(FIRDynamicLinkComponents *)components {
NSDictionary *suffixParametersDict = metadata[@"suffix"]; FIRDynamicLinkNavigationInfoParameters *navigationParams = [FIRDynamicLinkNavigationInfoParameters parameters];
if (suffixParametersDict) { if (navigationData[@"forcedRedirectEnabled"]) {
FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options]; navigationParams.forcedRedirectEnabled = navigationData[@"forcedRedirectEnabled"];
if ([suffixParametersDict[@"option"] isEqual: @"SHORT"]) {
options.pathLength = FIRShortDynamicLinkPathLengthShort;
}
else if ([suffixParametersDict[@"option"] isEqual: @"UNGUESSABLE"]) {
options.pathLength = FIRShortDynamicLinkPathLengthUnguessable;
}
components.options = options;
} }
components.navigationInfoParameters = navigationParams;
}
- (void)setSocialParameters:(NSDictionary *)socialData
components:(FIRDynamicLinkComponents *)components {
FIRDynamicLinkSocialMetaTagParameters *socialParams = [FIRDynamicLinkSocialMetaTagParameters parameters];
if (socialData[@"descriptionText"]) {
socialParams.descriptionText = socialData[@"descriptionText"];
}
if (socialData[@"imageUrl"]) {
socialParams.imageURL = [NSURL URLWithString:socialData[@"imageUrl"]];
}
if (socialData[@"title"]) {
socialParams.title = socialData[@"title"];
}
components.socialMetaTagParameters = socialParams;
} }
- (NSArray<NSString *> *)supportedEvents { - (NSArray<NSString *> *)supportedEvents {
@ -249,3 +285,4 @@ RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPr
@implementation RNFirebaseLinks @implementation RNFirebaseLinks
@end @end
#endif #endif

View File

@ -13,6 +13,7 @@ export const NAMESPACE = 'instanceid';
export default class InstanceId extends ModuleBase { export default class InstanceId extends ModuleBase {
constructor(app: App) { constructor(app: App) {
super(app, { super(app, {
hasShards: false,
moduleName: MODULE_NAME, moduleName: MODULE_NAME,
multiApp: false, multiApp: false,
namespace: NAMESPACE, namespace: NAMESPACE,

View File

@ -23,6 +23,7 @@ export default class Invites extends ModuleBase {
constructor(app: App) { constructor(app: App) {
super(app, { super(app, {
events: NATIVE_EVENTS, events: NATIVE_EVENTS,
hasShards: false,
moduleName: MODULE_NAME, moduleName: MODULE_NAME,
multiApp: false, multiApp: false,
namespace: NAMESPACE, namespace: NAMESPACE,

View File

@ -0,0 +1,79 @@
/**
* @flow
* AnalyticsParameters representation wrapper
*/
import type DynamicLink from './DynamicLink';
import type { NativeAnalyticsParameters } from './types';
export default class AnalyticsParameters {
_campaign: string | void;
_content: string | void;
_link: DynamicLink;
_medium: string | void;
_source: string | void;
_term: string | void;
constructor(link: DynamicLink) {
this._link = link;
}
/**
*
* @param campaign
* @returns {DynamicLink}
*/
setCampaign(campaign: string): DynamicLink {
this._campaign = campaign;
return this._link;
}
/**
*
* @param content
* @returns {DynamicLink}
*/
setContent(content: string): DynamicLink {
this._content = content;
return this._link;
}
/**
*
* @param medium
* @returns {DynamicLink}
*/
setMedium(medium: string): DynamicLink {
this._medium = medium;
return this._link;
}
/**
*
* @param source
* @returns {DynamicLink}
*/
setSource(source: string): DynamicLink {
this._source = source;
return this._link;
}
/**
*
* @param term
* @returns {DynamicLink}
*/
setTerm(term: string): DynamicLink {
this._term = term;
return this._link;
}
build(): NativeAnalyticsParameters {
return {
campaign: this._campaign,
content: this._content,
medium: this._medium,
source: this._source,
term: this._term,
};
}
}

View File

@ -0,0 +1,60 @@
/**
* @flow
* AndroidParameters representation wrapper
*/
import type DynamicLink from './DynamicLink';
import type { NativeAndroidParameters } from './types';
export default class AndroidParameters {
_fallbackUrl: string | void;
_link: DynamicLink;
_minimumVersion: number | void;
_packageName: string | void;
constructor(link: DynamicLink) {
this._link = link;
}
/**
*
* @param fallbackUrl
* @returns {DynamicLink}
*/
setFallbackUrl(fallbackUrl: string): DynamicLink {
this._fallbackUrl = fallbackUrl;
return this._link;
}
/**
*
* @param minimumVersion
* @returns {DynamicLink}
*/
setMinimumVersion(minimumVersion: number): DynamicLink {
this._minimumVersion = minimumVersion;
return this._link;
}
/**
*
* @param packageName
* @returns {DynamicLink}
*/
setPackageName(packageName: string): DynamicLink {
this._packageName = packageName;
return this._link;
}
build(): NativeAndroidParameters {
if ((this._fallbackUrl || this._minimumVersion) && !this._packageName) {
throw new Error(
'AndroidParameters: Missing required `packageName` property'
);
}
return {
fallbackUrl: this._fallbackUrl,
minimumVersion: this._minimumVersion,
packageName: this._packageName,
};
}
}

View File

@ -0,0 +1,79 @@
/**
* @flow
* DynamicLink representation wrapper
*/
import AnalyticsParameters from './AnalyticsParameters';
import AndroidParameters from './AndroidParameters';
import IOSParameters from './IOSParameters';
import ITunesParameters from './ITunesParameters';
import NavigationParameters from './NavigationParameters';
import SocialParameters from './SocialParameters';
import type { NativeDynamicLink } from './types';
export default class DynamicLink {
_analytics: AnalyticsParameters;
_android: AndroidParameters;
_dynamicLinkDomain: string;
_ios: IOSParameters;
_itunes: ITunesParameters;
_link: string;
_navigation: NavigationParameters;
_social: SocialParameters;
constructor(link: string, dynamicLinkDomain: string) {
this._analytics = new AnalyticsParameters(this);
this._android = new AndroidParameters(this);
this._dynamicLinkDomain = dynamicLinkDomain;
this._ios = new IOSParameters(this);
this._itunes = new ITunesParameters(this);
this._link = link;
this._navigation = new NavigationParameters(this);
this._social = new SocialParameters(this);
}
get analytics(): AnalyticsParameters {
return this._analytics;
}
get android(): AndroidParameters {
return this._android;
}
get ios(): IOSParameters {
return this._ios;
}
get itunes(): ITunesParameters {
return this._itunes;
}
get navigation(): NavigationParameters {
return this._navigation;
}
get social(): SocialParameters {
return this._social;
}
build(): NativeDynamicLink {
if (!this._link) {
throw new Error('DynamicLink: Missing required `link` property');
} else if (!this._dynamicLinkDomain) {
throw new Error(
'DynamicLink: Missing required `dynamicLinkDomain` property'
);
}
return {
analytics: this._analytics.build(),
android: this._android.build(),
dynamicLinkDomain: this._dynamicLinkDomain,
ios: this._ios.build(),
itunes: this._itunes.build(),
link: this._link,
navigation: this._navigation.build(),
social: this._social.build(),
};
}
}

View File

@ -0,0 +1,114 @@
/**
* @flow
* IOSParameters representation wrapper
*/
import type DynamicLink from './DynamicLink';
import type { NativeIOSParameters } from './types';
export default class IOSParameters {
_appStoreId: string | void;
_bundleId: string | void;
_customScheme: string | void;
_fallbackUrl: string | void;
_iPadBundleId: string | void;
_iPadFallbackUrl: string | void;
_link: DynamicLink;
_minimumVersion: string | void;
constructor(link: DynamicLink) {
this._link = link;
}
/**
*
* @param appStoreId
* @returns {DynamicLink}
*/
setAppStoreId(appStoreId: string): DynamicLink {
this._appStoreId = appStoreId;
return this._link;
}
/**
*
* @param bundleId
* @returns {DynamicLink}
*/
setBundleId(bundleId: string): DynamicLink {
this._bundleId = bundleId;
return this._link;
}
/**
*
* @param customScheme
* @returns {DynamicLink}
*/
setCustomScheme(customScheme: string): DynamicLink {
this._customScheme = customScheme;
return this._link;
}
/**
*
* @param fallbackUrl
* @returns {DynamicLink}
*/
setFallbackUrl(fallbackUrl: string): DynamicLink {
this._fallbackUrl = fallbackUrl;
return this._link;
}
/**
*
* @param iPadBundleId
* @returns {DynamicLink}
*/
setIPadBundleId(iPadBundleId: string): DynamicLink {
this._iPadBundleId = iPadBundleId;
return this._link;
}
/**
*
* @param iPadFallbackUrl
* @returns {DynamicLink}
*/
setIPadFallbackUrl(iPadFallbackUrl: string): DynamicLink {
this._iPadFallbackUrl = iPadFallbackUrl;
return this._link;
}
/**
*
* @param minimumVersion
* @returns {DynamicLink}
*/
setMinimumVersion(minimumVersion: string): DynamicLink {
this._minimumVersion = minimumVersion;
return this._link;
}
build(): NativeIOSParameters {
if (
(this._appStoreId ||
this._customScheme ||
this._fallbackUrl ||
this._iPadBundleId ||
this._iPadFallbackUrl ||
this._minimumVersion) &&
!this._bundleId
) {
throw new Error('IOSParameters: Missing required `bundleId` property');
}
return {
appStoreId: this._appStoreId,
bundleId: this._bundleId,
customScheme: this._customScheme,
fallbackUrl: this._fallbackUrl,
iPadBundleId: this._iPadBundleId,
iPadFallbackUrl: this._iPadFallbackUrl,
minimumVersion: this._minimumVersion,
};
}
}

View File

@ -0,0 +1,55 @@
/**
* @flow
* ITunesParameters representation wrapper
*/
import type DynamicLink from './DynamicLink';
import type { NativeITunesParameters } from './types';
export default class ITunesParameters {
_affiliateToken: string | void;
_campaignToken: string | void;
_link: DynamicLink;
_providerToken: string | void;
constructor(link: DynamicLink) {
this._link = link;
}
/**
*
* @param affiliateToken
* @returns {DynamicLink}
*/
setAffiliateToken(affiliateToken: string): DynamicLink {
this._affiliateToken = affiliateToken;
return this._link;
}
/**
*
* @param campaignToken
* @returns {DynamicLink}
*/
setCampaignToken(campaignToken: string): DynamicLink {
this._campaignToken = campaignToken;
return this._link;
}
/**
*
* @param providerToken
* @returns {DynamicLink}
*/
setProviderToken(providerToken: string): DynamicLink {
this._providerToken = providerToken;
return this._link;
}
build(): NativeITunesParameters {
return {
affiliateToken: this._affiliateToken,
campaignToken: this._campaignToken,
providerToken: this._providerToken,
};
}
}

View File

@ -0,0 +1,31 @@
/**
* @flow
* NavigationParameters representation wrapper
*/
import type DynamicLink from './DynamicLink';
import type { NativeNavigationParameters } from './types';
export default class NavigationParameters {
_forcedRedirectEnabled: string | void;
_link: DynamicLink;
constructor(link: DynamicLink) {
this._link = link;
}
/**
*
* @param forcedRedirectEnabled
* @returns {DynamicLink}
*/
setForcedRedirectEnabled(forcedRedirectEnabled: string): DynamicLink {
this._forcedRedirectEnabled = forcedRedirectEnabled;
return this._link;
}
build(): NativeNavigationParameters {
return {
forcedRedirectEnabled: this._forcedRedirectEnabled,
};
}
}

View File

@ -0,0 +1,55 @@
/**
* @flow
* SocialParameters representation wrapper
*/
import type DynamicLink from './DynamicLink';
import type { NativeSocialParameters } from './types';
export default class SocialParameters {
_descriptionText: string | void;
_imageUrl: string | void;
_link: DynamicLink;
_title: string | void;
constructor(link: DynamicLink) {
this._link = link;
}
/**
*
* @param descriptionText
* @returns {DynamicLink}
*/
setDescriptionText(descriptionText: string): DynamicLink {
this._descriptionText = descriptionText;
return this._link;
}
/**
*
* @param imageUrl
* @returns {DynamicLink}
*/
setImageUrl(imageUrl: string): DynamicLink {
this._imageUrl = imageUrl;
return this._link;
}
/**
*
* @param title
* @returns {DynamicLink}
*/
setTitle(title: string): DynamicLink {
this._title = title;
return this._link;
}
build(): NativeSocialParameters {
return {
descriptionText: this._descriptionText,
imageUrl: this._imageUrl,
title: this._title,
};
}
}

View File

@ -2,10 +2,10 @@
* @flow * @flow
* Dynamic Links representation wrapper * Dynamic Links representation wrapper
*/ */
import DynamicLink from './DynamicLink';
import { SharedEventEmitter } from '../../utils/events'; import { SharedEventEmitter } from '../../utils/events';
import { getLogger } from '../../utils/log'; import { getLogger } from '../../utils/log';
import ModuleBase from '../../utils/ModuleBase'; import ModuleBase from '../../utils/ModuleBase';
import { areObjectKeysContainedInOther, isObject, isString } from '../../utils';
import { getNativeModule } from '../../utils/native'; import { getNativeModule } from '../../utils/native';
import type App from '../core/app'; import type App from '../core/app';
@ -15,59 +15,6 @@ const NATIVE_EVENTS = ['links_link_received'];
export const MODULE_NAME = 'RNFirebaseLinks'; export const MODULE_NAME = 'RNFirebaseLinks';
export const NAMESPACE = 'links'; export const NAMESPACE = 'links';
function validateParameters(parameters: Object): void {
const suportedParametersObject = {
dynamicLinkDomain: 'string',
link: 'string',
androidInfo: {
androidPackageName: 'string',
androidFallbackLink: 'string',
androidMinPackageVersionCode: 'string',
androidLink: 'string',
},
iosInfo: {
iosBundleId: 'string',
iosFallbackLink: 'string',
iosCustomScheme: 'string',
iosIpadFallbackLink: 'string',
iosIpadBundleId: 'string',
iosAppStoreId: 'string',
},
socialMetaTagInfo: {
socialTitle: 'string',
socialDescription: 'string',
socialImageLink: 'string',
},
suffix: {
option: 'string',
},
};
if (!areObjectKeysContainedInOther(parameters, suportedParametersObject)) {
throw new Error('Invalid Parameters.');
}
}
function checkForMandatoryParameters(parameters: Object): void {
if (!isString(parameters.dynamicLinkDomain)) {
throw new Error('No dynamicLinkDomain was specified.');
}
if (!isString(parameters.link)) {
throw new Error('No link was specified.');
}
if (
isObject(parameters.androidInfo) &&
!isString(parameters.androidInfo.androidPackageName)
) {
throw new Error('No androidPackageName was specified.');
}
if (
isObject(parameters.iosInfo) &&
!isString(parameters.iosInfo.iosBundleId)
) {
throw new Error('No iosBundleId was specified.');
}
}
/** /**
* @class Links * @class Links
*/ */
@ -96,11 +43,9 @@ export default class Links extends ModuleBase {
* @param parameters * @param parameters
* @returns {Promise.<String>} * @returns {Promise.<String>}
*/ */
createDynamicLink(parameters: Object = {}): Promise<string> { createDynamicLink(link: DynamicLink): Promise<string> {
try { try {
checkForMandatoryParameters(parameters); return getNativeModule(this).createDynamicLink(link.build());
validateParameters(parameters);
return getNativeModule(this).createDynamicLink(parameters);
} catch (error) { } catch (error) {
return Promise.reject(error); return Promise.reject(error);
} }
@ -111,11 +56,12 @@ export default class Links extends ModuleBase {
* @param parameters * @param parameters
* @returns {Promise.<String>} * @returns {Promise.<String>}
*/ */
createShortDynamicLink(parameters: Object = {}): Promise<String> { createShortDynamicLink(
link: DynamicLink,
type?: 'SHORT' | 'UNGUESSABLE'
): Promise<String> {
try { try {
checkForMandatoryParameters(parameters); return getNativeModule(this).createShortDynamicLink(link.build(), type);
validateParameters(parameters);
return getNativeModule(this).createShortDynamicLink(parameters);
} catch (error) { } catch (error) {
return Promise.reject(error); return Promise.reject(error);
} }

View File

@ -0,0 +1,53 @@
/**
* @flow
*/
export type NativeAnalyticsParameters = {|
campaign?: string,
content?: string,
medium?: string,
source?: string,
term?: string,
|};
export type NativeAndroidParameters = {|
fallbackUrl?: string,
minimumVersion?: number,
packageName?: string,
|};
export type NativeIOSParameters = {|
appStoreId?: string,
bundleId?: string,
customScheme?: string,
fallbackUrl?: string,
iPadBundleId?: string,
iPadFallbackUrl?: string,
minimumVersion?: string,
|};
export type NativeITunesParameters = {|
affiliateToken?: string,
campaignToken?: string,
providerToken?: string,
|};
export type NativeNavigationParameters = {|
forcedRedirectEnabled?: string,
|};
export type NativeSocialParameters = {|
descriptionText?: string,
imageUrl?: string,
title?: string,
|};
export type NativeDynamicLink = {|
analytics: NativeAnalyticsParameters,
android: NativeAndroidParameters,
dynamicLinkDomain: string,
ios: NativeIOSParameters,
itunes: NativeITunesParameters,
link: string,
navigation: NativeNavigationParameters,
social: NativeSocialParameters,
|};

View File

@ -76,6 +76,7 @@ export default class Notifications extends ModuleBase {
constructor(app: App) { constructor(app: App) {
super(app, { super(app, {
events: NATIVE_EVENTS, events: NATIVE_EVENTS,
hasShards: false,
moduleName: MODULE_NAME, moduleName: MODULE_NAME,
multiApp: false, multiApp: false,
namespace: NAMESPACE, namespace: NAMESPACE,