Skip to content

Commit

Permalink
feat(dynamic-links): add support for utmParameters (#5593)
Browse files Browse the repository at this point in the history
if you resolve a short link that was built with utm parameters, they
will come through now on the returned link

Co-authored-by: Mike Hardy <github@mikehardy.net>
  • Loading branch information
Minishlink and mikehardy committed Aug 15, 2021
1 parent 4e25bf6 commit 3002caf
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import com.facebook.react.bridge.*;
import com.google.android.gms.tasks.Tasks;
Expand All @@ -41,6 +42,7 @@ public class ReactNativeFirebaseDynamicLinksModule extends ReactNativeFirebaseMo

private String initialLinkUrl = null;
private int initialLinkMinimumVersion = 0;
private WritableMap initialLinkUtmParameters = new WritableNativeMap();

/** Ensures calls to getInitialLink only tries to retrieve the link from getDynamicLink once. */
private boolean gotInitialLink = false;
Expand Down Expand Up @@ -180,14 +182,15 @@ public void getInitialLink(Promise promise) {
if (pendingDynamicLinkData != null) {
initialLinkUrl = pendingDynamicLinkData.getLink().toString();
initialLinkMinimumVersion = pendingDynamicLinkData.getMinimumAppVersion();
initialLinkUtmParameters = Arguments.makeNativeMap(pendingDynamicLinkData.getUtmParameters());
}

// Guard against the scenario where the app was launched using a dynamic link,
// then, the app was backgrounded using the Back button, and resumed from the
// Overview (screen).
if (initialLinkUrl != null && !launchedFromHistory) {
promise.resolve(
dynamicLinkToWritableMap(initialLinkUrl, initialLinkMinimumVersion));
dynamicLinkToWritableMap(initialLinkUrl, initialLinkMinimumVersion, initialLinkUtmParameters));
} else {
promise.resolve(null);
}
Expand All @@ -214,7 +217,8 @@ public void resolveLink(String link, Promise promise) {
&& linkData.getLink().toString() != null) {
String linkUrl = linkData.getLink().toString();
int linkMinimumVersion = linkData.getMinimumAppVersion();
promise.resolve(dynamicLinkToWritableMap(linkUrl, linkMinimumVersion));
Bundle linkUtmParameters = linkData.getUtmParameters();
promise.resolve(dynamicLinkToWritableMap(linkUrl, linkMinimumVersion, Arguments.makeNativeMap(linkUtmParameters)));
} else {
rejectPromiseWithCodeAndMessage(promise, "not-found", "Dynamic link not found");
}
Expand All @@ -229,7 +233,7 @@ public void resolveLink(String link, Promise promise) {
}
}

private WritableMap dynamicLinkToWritableMap(String url, int minVersion) {
private WritableMap dynamicLinkToWritableMap(String url, int minVersion, WritableMap utmParameters) {
WritableMap writableMap = Arguments.createMap();

writableMap.putString("url", url);
Expand All @@ -240,6 +244,8 @@ private WritableMap dynamicLinkToWritableMap(String url, int minVersion) {
writableMap.putInt("minimumAppVersion", minVersion);
}

writableMap.putMap("utmParameters", utmParameters);

return writableMap;
}

Expand Down Expand Up @@ -435,7 +441,8 @@ public void onNewIntent(Intent intent) {
"dynamic_links_link_received",
dynamicLinkToWritableMap(
pendingDynamicLinkData.getLink().toString(),
pendingDynamicLinkData.getMinimumAppVersion())));
pendingDynamicLinkData.getMinimumAppVersion(),
Arguments.makeNativeMap(pendingDynamicLinkData.getUtmParameters()))));
}
} else {
Log.e(
Expand Down
2 changes: 2 additions & 0 deletions packages/dynamic-links/e2e/dynamicLinks.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ describe('dynamicLinks()', function () {

dynamicLink.should.be.an.Object();
dynamicLink.url.should.equal('https://rnfirebase.io');
dynamicLink.utmParameters.should.eql({});
});
});

Expand All @@ -172,6 +173,7 @@ describe('dynamicLinks()', function () {

spy.getCall(0).args[0].should.be.an.Object();
spy.getCall(0).args[0].url.should.equal('https://invertase.io/hire-us');
spy.getCall(0).args[0].utmParameters.should.eql({});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static NSString *const LINK_RECEIVED_EVENT = @"dynamic_links_link_received";
@interface RNFBDynamicLinksAppDelegateInterceptor : NSObject <UIApplicationDelegate>
@property(strong, readwrite) NSString *_Nullable initialLinkUrl;
@property(strong, readwrite) NSString *_Nullable initialLinkMinimumAppVersion;
@property(strong, readwrite) NSDictionary<NSString *, id> *_Nonnull initialLinkUtmParametersDictionary;

+ (instancetype)sharedInstance;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ + (instancetype)sharedInstance {
sharedInstance = [[RNFBDynamicLinksAppDelegateInterceptor alloc] init];
sharedInstance.initialLinkUrl = nil;
sharedInstance.initialLinkMinimumAppVersion = nil;
sharedInstance.initialLinkUtmParametersDictionary = @{};
[GULAppDelegateSwizzler proxyOriginalDelegate];
[GULAppDelegateSwizzler registerAppDelegateInterceptor:sharedInstance];
});
Expand Down Expand Up @@ -64,6 +65,7 @@ - (BOOL)application:(UIApplication *)application
if (_initialLinkUrl == nil) {
_initialLinkUrl = dynamicLink.url.absoluteString;
_initialLinkMinimumAppVersion = dynamicLink.minimumAppVersion;
_initialLinkUtmParametersDictionary = dynamicLink.utmParametersDictionary;
}
[[RNFBRCTEventEmitter shared]
sendEventWithName:LINK_RECEIVED_EVENT
Expand All @@ -72,6 +74,9 @@ - (BOOL)application:(UIApplication *)application
@"minimumAppVersion" : dynamicLink.minimumAppVersion == nil
? [NSNull null]
: dynamicLink.minimumAppVersion,
@"utmParameters": dynamicLink.utmParametersDictionary == nil
? @{}
: dynamicLink.utmParametersDictionary,
}];
}

Expand All @@ -91,6 +96,7 @@ - (BOOL)application:(UIApplication *)application
if (_initialLinkUrl == nil) {
_initialLinkUrl = dynamicLink.url.absoluteString;
_initialLinkMinimumAppVersion = dynamicLink.minimumAppVersion;
_initialLinkUtmParametersDictionary = dynamicLink.utmParametersDictionary;
}
[[RNFBRCTEventEmitter shared]
sendEventWithName:LINK_RECEIVED_EVENT
Expand All @@ -99,6 +105,9 @@ - (BOOL)application:(UIApplication *)application
@"minimumAppVersion" : dynamicLink.minimumAppVersion == nil
? [NSNull null]
: dynamicLink.minimumAppVersion,
@"utmParameters": dynamicLink.utmParametersDictionary == nil
? @{}
: dynamicLink.utmParametersDictionary,
}];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ - (id)init {
@"url" : dynamicLink.url.absoluteString,
@"minimumAppVersion" : dynamicLink.minimumAppVersion == nil ? [NSNull null]
: dynamicLink.minimumAppVersion,
@"utmParameters": dynamicLink.utmParametersDictionary == nil ? @{}
: dynamicLink.utmParametersDictionary,
});
} else if ([RNFBDynamicLinksAppDelegateInterceptor sharedInstance].initialLinkUrl != nil) {
resolve(@{
Expand All @@ -144,6 +146,10 @@ - (id)init {
.initialLinkMinimumAppVersion == nil
? [NSNull null]
: [RNFBDynamicLinksAppDelegateInterceptor sharedInstance].initialLinkMinimumAppVersion,
@"utmParameters": [RNFBDynamicLinksAppDelegateInterceptor sharedInstance]
.initialLinkUtmParametersDictionary == nil
? @{}
: [RNFBDynamicLinksAppDelegateInterceptor sharedInstance].initialLinkUtmParametersDictionary,
});
} else {
resolve([NSNull null]);
Expand All @@ -166,6 +172,9 @@ - (id)init {
@"minimumAppVersion" : dynamicLink.minimumAppVersion == nil
? [NSNull null]
: dynamicLink.minimumAppVersion,
@"utmParameters": dynamicLink.utmParametersDictionary == nil
? @{}
: dynamicLink.utmParametersDictionary,
});
} else if (!error &&
[RNFBDynamicLinksAppDelegateInterceptor sharedInstance].initialLinkUrl != nil) {
Expand All @@ -176,6 +185,10 @@ - (id)init {
? [NSNull null]
: [RNFBDynamicLinksAppDelegateInterceptor sharedInstance]
.initialLinkMinimumAppVersion,
@"utmParameters": [RNFBDynamicLinksAppDelegateInterceptor sharedInstance]
.initialLinkUtmParametersDictionary == nil
? @{}
: [RNFBDynamicLinksAppDelegateInterceptor sharedInstance].initialLinkUtmParametersDictionary,
});
} else if (error) {
[RNFBSharedUtils rejectPromiseWithUserInfo:reject
Expand All @@ -201,6 +214,10 @@ - (id)init {
.initialLinkMinimumAppVersion == nil
? [NSNull null]
: [RNFBDynamicLinksAppDelegateInterceptor sharedInstance].initialLinkMinimumAppVersion,
@"utmParameters": [RNFBDynamicLinksAppDelegateInterceptor sharedInstance]
.initialLinkUtmParametersDictionary == nil
? @{}
: [RNFBDynamicLinksAppDelegateInterceptor sharedInstance].initialLinkUtmParametersDictionary,
});
} else {
resolve([NSNull null]);
Expand All @@ -217,6 +234,8 @@ - (id)init {
@"url" : dynamicLink.url.absoluteString,
@"minimumAppVersion" : dynamicLink.minimumAppVersion == nil ? [NSNull null]
: dynamicLink.minimumAppVersion,
@"utmParameters": dynamicLink.utmParametersDictionary == nil ? @{}
: dynamicLink.utmParametersDictionary,
});
} else if (!error ||
(error && [error.localizedDescription containsString:@"dynamicLinks error 404"])) {
Expand Down
7 changes: 7 additions & 0 deletions packages/dynamic-links/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,13 @@ export namespace FirebaseDynamicLinksTypes {
* On iOS this returns a string value representing the minimum app version (not the iOS system version).
*/
minimumAppVersion: number | string | null;

/**
* The potential UTM parameters linked to this dynamic link
*
* It will only work for short links, not long links
*/
utmParameters: Record<string, string>;
}

/**
Expand Down

1 comment on commit 3002caf

@vercel
Copy link

@vercel vercel bot commented on 3002caf Aug 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.