react-native-firebase
react-native-firebase copied to clipboard
DynamicLinks builder does not support ofl / general offline param
This was documented as added quite some time ago in iOS:
- firebase-ios-sdk 4.7.0 in 2017 added it https://firebase.google.com/support/release-notes/ios#dynamic-links_36
But then I look in the iOS SDK reference and cannot find it there or in the code, and I can't find it in the Android one either.
There is no dynamic links module for firebase-js-sdk (which would normally give us a pattern to work off of, if we make an API that isn't represented by the native iOS/Android SDKs and just implement it ourselves)
So, I'm not sure how we can support this well but I'll create an enhancement issue at least to capture this
Originally posted by @mikehardy in https://github.com/invertase/react-native-firebase/discussions/5737#discussioncomment-1379884
Hello 👋, to help manage issues we automatically close stale issues. This issue has been automatically marked as stale because it has not had activity for quite some time. Has this issue been fixed, or does it still require the community's attention?
This issue will be closed in 15 days if no further activity occurs. Thank you for your contributions.
@mikehardy Could you tell me by when we can expect this enhancement in the react-native-firebase module? This feature is achievable if we add the support for "ofl" parameter. This is supported in native firebase sdks. On trying to create a patch, I got what I wanted for iOS but not for android as "DynamicLinks.java" file is in read mode. I'm not able to edit source code for Firebase in Android.
For ios:
RNFBDynamicLinksModule.m
- (FIRDynamicLinkComponents *)createDynamicLinkComponents:(NSDictionary *)dynamicLinkDict {
NSURL *link = [NSURL URLWithString:dynamicLinkDict[@"link"]];
FIRDynamicLinkComponents *linkComponents =
[FIRDynamicLinkComponents componentsWithLink:link
domainURIPrefix:dynamicLinkDict[@"domainUriPrefix"]];
[self buildAnalyticsParameters:dynamicLinkDict[@"analytics"] components:linkComponents];
[self buildAndroidParameters:dynamicLinkDict[@"android"] components:linkComponents];
[self buildIosParameters:dynamicLinkDict[@"ios"] components:linkComponents];
[self buildItunesParameters:dynamicLinkDict[@"itunes"] components:linkComponents];
[self buildNavigationParameters:dynamicLinkDict[@"navigation"] components:linkComponents];
[self buildSocialParameters:dynamicLinkDict[@"social"] components:linkComponents];
// Is this the part that is new?
[self buildOtherPlatformParameters:dynamicLinkDict[@"otherPlatformParameters"] components:linkComponents];
return linkComponents;
}
- (void)buildOtherPlatformParameters:(NSDictionary *)otherdDict
components:(FIRDynamicLinkComponents *)linkComponents {
if (otherdDict == nil) return;
FIRDynamicLinkOtherPlatformParameters *otherParams =
[FIRDynamicLinkOtherPlatformParameters parameters];
if (otherdDict[@"fallbackUrl"]) {
otherParams.fallbackUrl = [NSURL URLWithString:otherdDict[@"fallbackUrl"]];
}
linkComponents.otherPlatformParameters = otherParams;
}
Hey @Nehal-Sanklecha !
I edited your comment to use triple-backticks around the whole block and the objective-c language specifier so it's easy to read
"DynamicLinks.java" file is in read mode
That is quite unexpected! There is no reason a git repository or npm module of an open source repository into a directory that you can control should have files that are read only. You may edit the java files to without restriction. I do it all the time. You are in control of your own machine
Could you tell me by when we can expect this enhancement
I don't think an open source repository ever carries any sorts of expectations on time of delivery, or at least it shouldn't. This is not currently on the roadmap. So the first moment you can actually have an expectation of delivery is when you post a PR and our CI kicks out a set of patch-package files for integration in to your project, since that relies on your own investment of time and is thus under your control
I'm particularly interested in this assertion:
This is supported in native firebase sdks
I have not seen it. Can you point to the upstream reference documentation where it is detailed? It appears you are using the "fallbackUrl" parameter ? Is that the one that generates the ofl in the link? If so that's news to me and must be why I missed it!
That looks like a PR we could easily ingest, and if you can get the Java edited as well and post a PR we can probably get this in as soon as CI finishes verifying it
@mikehardy Apologies for the delayed response.
You may edit the java files without restriction
Since I'm not able to edit the file I'm not sure how do I create a PR for this enhancement
Link for the supported feature in native firebase SDK
https://firebase.google.com/docs/dynamic-links/create-manually
Check for the Other platform parameters field.
In my comment, where you've asked Is this the part that is new?
Yes, that's the line of code I've added to support desktop fallback URL in iOS. I want to do the same in Android.
Since I'm not able to edit the file
If you are not able to edit files on your own computer, which is under your control, I'm not sure how much help I can be
You are a software developer, you alter text files to change lines of code. These are text files on your computer. You may alter them at will
@Nehal-Sanklecha I just sent up a PR that fixes this issue for you. For some reason GitHub wouldn't allow me to submit a PR of just the changes, but here's my patch file if you want to implement it manually:
@react-native-firebase+dynamic-links+14.12.0.patch
diff --git a/node_modules/@react-native-firebase/dynamic-links/android/src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java b/node_modules/@react-native-firebase/dynamic-links/android/src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java
index b806de3..706564b 100644
--- a/node_modules/@react-native-firebase/dynamic-links/android/src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java
+++ b/node_modules/@react-native-firebase/dynamic-links/android/src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java
@@ -291,6 +291,15 @@ public class ReactNativeFirebaseDynamicLinksModule extends ReactNativeFirebaseMo
buildNavigationParameters(dynamicLinkMap.getMap("navigation"), builder);
}
+ if (dynamicLinkMap.hasKey("otherPlatform")) {
+ if (dynamicLinkMap.getMap("otherPlatform").hasKey("fallbackUrl")) {
+ String OTHER_PLATFORM_LINK_KEY = "ofl";
+ String linkUrl = String.valueOf(builder.buildDynamicLink().getUri());
+ linkUrl += '&' + OTHER_PLATFORM_LINK_KEY + '=' + dynamicLinkMap.getMap("otherPlatform").getString("fallbackUrl");
+ builder.setLongLink(Uri.parse(linkUrl));
+ }
+ }
+
return builder;
}
diff --git a/node_modules/@react-native-firebase/dynamic-links/ios/RNFBDynamicLinks/RNFBDynamicLinksModule.m b/node_modules/@react-native-firebase/dynamic-links/ios/RNFBDynamicLinks/RNFBDynamicLinksModule.m
index 17aff6c..7483a67 100644
--- a/node_modules/@react-native-firebase/dynamic-links/ios/RNFBDynamicLinks/RNFBDynamicLinksModule.m
+++ b/node_modules/@react-native-firebase/dynamic-links/ios/RNFBDynamicLinks/RNFBDynamicLinksModule.m
@@ -276,6 +276,7 @@ - (FIRDynamicLinkComponents *)createDynamicLinkComponents:(NSDictionary *)dynami
[self buildItunesParameters:dynamicLinkDict[@"itunes"] components:linkComponents];
[self buildNavigationParameters:dynamicLinkDict[@"navigation"] components:linkComponents];
[self buildSocialParameters:dynamicLinkDict[@"social"] components:linkComponents];
+ [self buildOtherPlatformParameters:dynamicLinkDict[@"otherPlatform"] components:linkComponents];
return linkComponents;
}
@@ -419,6 +420,18 @@ - (void)buildSocialParameters:(NSDictionary *)socialDict
linkComponents.socialMetaTagParameters = socialParams;
}
+- (void)buildOtherPlatformParameters:(NSDictionary *)otherDict
+ components:(FIRDynamicLinkComponents *)linkComponents {
+ if (otherDict == nil) return;
+
+ FIRDynamicLinkOtherPlatformParameters *otherParams =
+ [FIRDynamicLinkOtherPlatformParameters parameters];
+ if (otherDict[@"fallbackUrl"]) {
+ otherParams.fallbackUrl = [NSURL URLWithString:otherDict[@"fallbackUrl"]];
+ }
+ linkComponents.otherPlatformParameters = otherParams;
+}
+
- (NSArray<NSString *> *)supportedEvents {
return @[];
}
diff --git a/node_modules/@react-native-firebase/dynamic-links/lib/builder.js b/node_modules/@react-native-firebase/dynamic-links/lib/builder.js
index 2b04224..f0d4e47 100644
--- a/node_modules/@react-native-firebase/dynamic-links/lib/builder.js
+++ b/node_modules/@react-native-firebase/dynamic-links/lib/builder.js
@@ -22,13 +22,14 @@ import buildIos from './builders/ios';
import buildItunes from './builders/itunes';
import buildNavigation from './builders/navigation';
import buildSocial from './builders/social';
+import buildOtherPlatform from './builders/otherPlatform';
export default function build(dynamicLinksParams) {
if (!isObject(dynamicLinksParams)) {
throw new Error("'dynamicLinksParams' must be an object.");
}
- const { link, domainUriPrefix, android, analytics, ios, itunes, navigation, social } =
+ const { link, domainUriPrefix, android, analytics, ios, itunes, navigation, social, otherPlatform } =
dynamicLinksParams;
if (!link) {
@@ -87,5 +88,9 @@ export default function build(dynamicLinksParams) {
params.social = buildSocial(social);
}
+ if (otherPlatform) {
+ params.otherPlatform = buildOtherPlatform(otherPlatform)
+ }
+
return params;
}
diff --git a/node_modules/@react-native-firebase/dynamic-links/lib/builders/otherPlatform.js b/node_modules/@react-native-firebase/dynamic-links/lib/builders/otherPlatform.js
new file mode 100644
index 0000000..6df1fa0
--- /dev/null
+++ b/node_modules/@react-native-firebase/dynamic-links/lib/builders/otherPlatform.js
@@ -0,0 +1,19 @@
+import { isObject, isString } from '@react-native-firebase/app/lib/common';
+
+export default function buildOtherPlatform(otherPlatformParameters) {
+ if (!isObject(otherPlatformParameters)) {
+ throw new Error("'dynamicLinksParams.otherPlatform' must be an object.");
+ }
+
+ const params = {}
+
+ if (otherPlatformParameters.fallbackUrl) {
+ if (!isString(otherPlatformParameters.fallbackUrl)) {
+ throw new Error("'dynamicLinksParams.otherPlatform.fallbackUrl' must be a string.");
+ }
+
+ params.fallbackUrl = otherPlatformParameters.fallbackUrl;
+ }
+
+ return params
+}
\ No newline at end of file
diff --git a/node_modules/@react-native-firebase/dynamic-links/lib/index.d.ts b/node_modules/@react-native-firebase/dynamic-links/lib/index.d.ts
index 2f13c96..22c2397 100644
--- a/node_modules/@react-native-firebase/dynamic-links/lib/index.d.ts
+++ b/node_modules/@react-native-firebase/dynamic-links/lib/index.d.ts
@@ -302,6 +302,32 @@ export namespace FirebaseDynamicLinksTypes {
title?: string;
}
+ /**
+ * The DynamicLinkOtherPlatformParameters interface provides functionality to
+ * open a custom URL on platforms beside Android and iOS. This is useful to
+ * specify a different behavior on desktop, like displaying a full web page
+ * of the app content/payload (as specified by param link) with another dynamic
+ * link to install the app.
+ *
+ * #### Example
+ *
+ * ```js
+ * const link = await firebase.dynamicLinks().buildLink({
+ * link: 'https://invertase.io',
+ * domainUriPrefix: 'https://xyz.page.link',
+ * otherPlatform: {
+ fallbackUrl: 'https://www.google.com/',
+ * }
+ * });
+ * ```
+ */
+ export interface DynamicLinkOtherPlatformParameters {
+ /**
+ * The URL to open on desktop.
+ */
+ fallbackUrl?: string;
+ }
+
/**
* The DynamicLinkParameters interface provides access to the Dynamic Link builder classes
* used to configure a created link.
@@ -359,6 +385,11 @@ export namespace FirebaseDynamicLinksTypes {
* Access social specific link parameters.
*/
social?: DynamicLinkSocialParameters;
+
+ /**
+ * Access other platform specific link parameters.
+ */
+ otherPlatform?: DynamicLinkOtherPlatformParameters
}
/**
tested it out on android, iOS, and desktop and it works as expected. hope that helps you.
@Nehal-Sanklecha
Yes, that's the line of code I've added to support desktop fallback URL in iOS. I want to do the same in Android.
It looks like you were trying to edit the DynamicLink class (owned by Firebase) in your screenshot.
The file that you need to be editing instead is:
@react-native-firebase/dynamic-links/android/src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java
and here's the code to fix the issue on android:
private DynamicLink.Builder createDynamicLinkBuilder(final ReadableMap dynamicLinkMap) {
DynamicLink.Builder builder = FirebaseDynamicLinks.getInstance().createDynamicLink();
builder.setLink(Uri.parse(dynamicLinkMap.getString("link")));
builder.setDomainUriPrefix(Objects.requireNonNull(dynamicLinkMap.getString("domainUriPrefix")));
if (dynamicLinkMap.hasKey("ios")) {
buildIosParameters(dynamicLinkMap.getMap("ios"), builder);
}
if (dynamicLinkMap.hasKey("itunes")) {
buildItunesParameters(dynamicLinkMap.getMap("itunes"), builder);
}
if (dynamicLinkMap.hasKey("social")) {
buildSocialParameters(dynamicLinkMap.getMap("social"), builder);
}
if (dynamicLinkMap.hasKey("android")) {
buildAndroidParameters(dynamicLinkMap.getMap("android"), builder);
}
if (dynamicLinkMap.hasKey("analytics")) {
buildAnalyticsParameters(dynamicLinkMap.getMap("analytics"), builder);
}
if (dynamicLinkMap.hasKey("navigation")) {
buildNavigationParameters(dynamicLinkMap.getMap("navigation"), builder);
}
/** NEW CODE STARTS HERE:
if (dynamicLinkMap.hasKey("otherPlatform")) {
if (dynamicLinkMap.getMap("otherPlatform").hasKey("fallbackUrl")) {
String OTHER_PLATFORM_LINK_KEY = "ofl";
String linkUrl = String.valueOf(builder.buildDynamicLink().getUri());
linkUrl += '&' + OTHER_PLATFORM_LINK_KEY + '=' + dynamicLinkMap.getMap("otherPlatform").getString("fallbackUrl");
builder.setLongLink(Uri.parse(linkUrl));
}
}
**/
return builder;
}
You were correct in that the iOS SDK exposes the ofl parameters, so I included that in the PR. The official Android SDK, however, does not have the same support for the ofl parameters - so to keep the interface constant we're just going to take the same formatted parameters otherPlatform?: { fallbackUrl?: string }.. pull out the ofl fallbackUrl (if present), set it as the longLink, and then manually append the provided ofl parameters to the end of the string and rebuild the link.
let me know if that solves your problem (as it did mine).
https://github.com/invertase/react-native-firebase/commit/bda3602b1047f31e9f5f0f6b93ffaea5fc66cc05