@ohos-ports/react-native-firebase-dynamic-links 0.0.0-stage → 22.4.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +971 -0
- package/LICENSE +32 -0
- package/README.md +53 -2
- package/RNFBDynamicLinks.podspec +49 -0
- package/android/.editorconfig +10 -0
- package/android/build.gradle +98 -0
- package/android/lint.xml +5 -0
- package/android/settings.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +8 -0
- package/android/src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java +507 -0
- package/android/src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksPackage.java +44 -0
- package/app.plugin.js +1 -0
- package/ios/RNFBDynamicLinks/RNFBDynamicLinksAppDelegateInterceptor.h +37 -0
- package/ios/RNFBDynamicLinks/RNFBDynamicLinksAppDelegateInterceptor.m +132 -0
- package/ios/RNFBDynamicLinks/RNFBDynamicLinksModule.h +28 -0
- package/ios/RNFBDynamicLinks/RNFBDynamicLinksModule.m +443 -0
- package/ios/RNFBDynamicLinks.xcodeproj/project.pbxproj +354 -0
- package/ios/RNFBDynamicLinks.xcodeproj/xcshareddata/IDETemplateMacros.plist +24 -0
- package/lib/builder.js +93 -0
- package/lib/builders/analytics.js +61 -0
- package/lib/builders/android.js +52 -0
- package/lib/builders/ios.js +76 -0
- package/lib/builders/itunes.js +49 -0
- package/lib/builders/navigation.js +37 -0
- package/lib/builders/otherPlatform.js +20 -0
- package/lib/builders/social.js +49 -0
- package/lib/index.d.ts +650 -0
- package/lib/index.js +119 -0
- package/lib/modular/index.d.ts +148 -0
- package/lib/modular/index.js +110 -0
- package/lib/version.js +2 -0
- package/package.json +42 -4
- package/plugin/build/index.d.ts +3 -0
- package/plugin/build/index.js +17 -0
- package/plugin/build/ios/appDelegate.d.ts +5 -0
- package/plugin/build/ios/appDelegate.js +86 -0
- package/plugin/build/ios/index.d.ts +2 -0
- package/plugin/build/ios/index.js +13 -0
- package/plugin/src/index.ts +15 -0
- package/plugin/src/ios/appDelegate.ts +92 -0
- package/plugin/src/ios/index.ts +3 -0
- package/plugin/tsconfig.json +9 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
package io.invertase.firebase.dynamiclinks;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import android.app.Activity;
|
|
21
|
+
import android.content.Intent;
|
|
22
|
+
import android.net.Uri;
|
|
23
|
+
import android.os.Bundle;
|
|
24
|
+
import android.util.Log;
|
|
25
|
+
import com.facebook.react.bridge.*;
|
|
26
|
+
import com.google.android.gms.tasks.Tasks;
|
|
27
|
+
import com.google.firebase.dynamiclinks.DynamicLink;
|
|
28
|
+
import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
|
|
29
|
+
import com.google.firebase.dynamiclinks.PendingDynamicLinkData;
|
|
30
|
+
import com.google.firebase.dynamiclinks.ShortDynamicLink;
|
|
31
|
+
import io.invertase.firebase.common.ReactNativeFirebaseEvent;
|
|
32
|
+
import io.invertase.firebase.common.ReactNativeFirebaseEventEmitter;
|
|
33
|
+
import io.invertase.firebase.common.ReactNativeFirebaseModule;
|
|
34
|
+
import java.util.Objects;
|
|
35
|
+
import javax.annotation.Nullable;
|
|
36
|
+
|
|
37
|
+
public class ReactNativeFirebaseDynamicLinksModule extends ReactNativeFirebaseModule
|
|
38
|
+
implements ActivityEventListener, LifecycleEventListener {
|
|
39
|
+
private static final String TAG = "DynamicLinks";
|
|
40
|
+
private static final String SHORT_LINK_TYPE_SHORT = "SHORT";
|
|
41
|
+
private static final String SHORT_LINK_TYPE_UNGUESSABLE = "UNGUESSABLE";
|
|
42
|
+
|
|
43
|
+
private String initialLinkUrl = null;
|
|
44
|
+
private int initialLinkMinimumVersion = 0;
|
|
45
|
+
|
|
46
|
+
/** Ensures calls to getInitialLink only tries to retrieve the link from getDynamicLink once. */
|
|
47
|
+
private boolean gotInitialLink = false;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Used by getInitialLink to check if the activity has been resumed. "host" refers to the host
|
|
51
|
+
* activity, in terms of {@link LifeCycleEventListener#onHostResume()}
|
|
52
|
+
*/
|
|
53
|
+
private boolean hostResumed = false;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Used by getInitialLink to check the current activity's intent flags to verify that the app
|
|
57
|
+
* hasn't been resumed from the Overview (history) screen.
|
|
58
|
+
*/
|
|
59
|
+
private boolean launchedFromHistory = false;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Holds the Promise that was passed to getInitialLink if getInitialLink was called before {@link
|
|
63
|
+
* com.facebook.react.common.LifecycleState#RESUMED} Lifecycle state.
|
|
64
|
+
*/
|
|
65
|
+
private Promise initialPromise = null;
|
|
66
|
+
|
|
67
|
+
ReactNativeFirebaseDynamicLinksModule(ReactApplicationContext reactContext) {
|
|
68
|
+
super(reactContext, TAG);
|
|
69
|
+
getReactApplicationContext().addActivityEventListener(this);
|
|
70
|
+
getReactApplicationContext().addLifecycleEventListener(this);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@Override
|
|
74
|
+
public void invalidate() {
|
|
75
|
+
getReactApplicationContext().removeActivityEventListener(this);
|
|
76
|
+
getReactApplicationContext().addLifecycleEventListener(this);
|
|
77
|
+
super.invalidate();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@ReactMethod
|
|
81
|
+
public void buildLink(ReadableMap dynamicLinkMap, Promise promise) {
|
|
82
|
+
Tasks.call(
|
|
83
|
+
getExecutor(),
|
|
84
|
+
() -> createDynamicLinkBuilder(dynamicLinkMap).buildDynamicLink().getUri().toString())
|
|
85
|
+
.addOnCompleteListener(
|
|
86
|
+
getExecutor(),
|
|
87
|
+
(task) -> {
|
|
88
|
+
if (task.isSuccessful()) {
|
|
89
|
+
promise.resolve(task.getResult());
|
|
90
|
+
} else {
|
|
91
|
+
Log.e(TAG, "RNFB: Unknown error while building Dynamic Link ", task.getException());
|
|
92
|
+
rejectPromiseWithCodeAndMessage(
|
|
93
|
+
promise, "build-failed", task.getException().getMessage());
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@ReactMethod
|
|
99
|
+
public void buildShortLink(ReadableMap dynamicLinkMap, String shortLinkType, Promise promise) {
|
|
100
|
+
Tasks.call(
|
|
101
|
+
getExecutor(),
|
|
102
|
+
() -> {
|
|
103
|
+
DynamicLink.Builder builder = createDynamicLinkBuilder(dynamicLinkMap);
|
|
104
|
+
if (SHORT_LINK_TYPE_SHORT.equals(shortLinkType)) {
|
|
105
|
+
return Tasks.await(builder.buildShortDynamicLink(ShortDynamicLink.Suffix.SHORT));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (SHORT_LINK_TYPE_UNGUESSABLE.equals(shortLinkType)) {
|
|
109
|
+
return Tasks.await(
|
|
110
|
+
builder.buildShortDynamicLink(ShortDynamicLink.Suffix.UNGUESSABLE));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return Tasks.await(builder.buildShortDynamicLink());
|
|
114
|
+
})
|
|
115
|
+
.addOnCompleteListener(
|
|
116
|
+
getExecutor(),
|
|
117
|
+
(task) -> {
|
|
118
|
+
if (task.isSuccessful()) {
|
|
119
|
+
// TODO implement after v6
|
|
120
|
+
// WritableMap shortLinkMap = Arguments.createMap();
|
|
121
|
+
// WritableArray shortLinkWarnings = Arguments.createArray();
|
|
122
|
+
// List<? extends ShortDynamicLink.Warning> warningsList =
|
|
123
|
+
// task.getResult().getWarnings();
|
|
124
|
+
// for (ShortDynamicLink.Warning warning : warningsList) {
|
|
125
|
+
// shortLinkWarnings.pushString(warning.getMessage());
|
|
126
|
+
// }
|
|
127
|
+
// shortLinkMap.putArray("warnings", shortLinkWarnings);
|
|
128
|
+
// shortLinkMap.putString("link", task.getResult().getShortLink().toString());
|
|
129
|
+
|
|
130
|
+
promise.resolve(task.getResult().getShortLink().toString());
|
|
131
|
+
} else {
|
|
132
|
+
Log.e(
|
|
133
|
+
TAG,
|
|
134
|
+
"RNFB: Unknown error while building Dynamic Link "
|
|
135
|
+
+ task.getException().getMessage());
|
|
136
|
+
rejectPromiseWithCodeAndMessage(
|
|
137
|
+
promise, "build-failed", task.getException().getMessage());
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@ReactMethod
|
|
143
|
+
public void getInitialLink(Promise promise) {
|
|
144
|
+
// Check if getDynamicLink() has already completed successfully.
|
|
145
|
+
// This ensures the initial link is returned once, if found.
|
|
146
|
+
if (gotInitialLink) {
|
|
147
|
+
promise.resolve(null);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Check for the case where getInitialLink
|
|
152
|
+
// runs before the LifeCycleState is RESUMED (e.g. BEFORE_CREATE or BEFORE_RESUME).
|
|
153
|
+
if (!hostResumed) {
|
|
154
|
+
// Use initialPromise to store the Promise that was passed and
|
|
155
|
+
// run it when LifeCycleState changes to RESUMED in onHostResume.
|
|
156
|
+
initialPromise = promise;
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
Activity currentActivity = getCurrentActivity();
|
|
161
|
+
// Shouldn't happen anymore, left as a guard.
|
|
162
|
+
if (currentActivity == null) {
|
|
163
|
+
promise.resolve(null);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
Intent currentIntent = currentActivity.getIntent();
|
|
168
|
+
if (currentIntent == null) {
|
|
169
|
+
promise.resolve(null);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Verify if the app was resumed from the Overview (history) screen.
|
|
174
|
+
launchedFromHistory =
|
|
175
|
+
(currentIntent != null)
|
|
176
|
+
&& ((currentIntent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0);
|
|
177
|
+
|
|
178
|
+
FirebaseDynamicLinks.getInstance()
|
|
179
|
+
.getDynamicLink(currentIntent)
|
|
180
|
+
.addOnCompleteListener(
|
|
181
|
+
task -> {
|
|
182
|
+
if (task.isSuccessful()) {
|
|
183
|
+
// Flag that the getDynamicLink() completed successfully,
|
|
184
|
+
// preventing future calls to from receiving the link, as if the link had been
|
|
185
|
+
// cleared.
|
|
186
|
+
gotInitialLink = true;
|
|
187
|
+
PendingDynamicLinkData pendingDynamicLinkData = task.getResult();
|
|
188
|
+
WritableMap initialLinkUtmParameters = new WritableNativeMap();
|
|
189
|
+
|
|
190
|
+
if (pendingDynamicLinkData != null) {
|
|
191
|
+
initialLinkUrl = pendingDynamicLinkData.getLink().toString();
|
|
192
|
+
initialLinkMinimumVersion = pendingDynamicLinkData.getMinimumAppVersion();
|
|
193
|
+
initialLinkUtmParameters =
|
|
194
|
+
Arguments.makeNativeMap(pendingDynamicLinkData.getUtmParameters());
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Guard against the scenario where the app was launched using a dynamic link,
|
|
198
|
+
// then, the app was backgrounded using the Back button, and resumed from the
|
|
199
|
+
// Overview (screen).
|
|
200
|
+
if (initialLinkUrl != null && !launchedFromHistory) {
|
|
201
|
+
promise.resolve(
|
|
202
|
+
dynamicLinkToWritableMap(
|
|
203
|
+
initialLinkUrl, initialLinkMinimumVersion, initialLinkUtmParameters));
|
|
204
|
+
} else {
|
|
205
|
+
promise.resolve(null);
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
rejectPromiseWithCodeAndMessage(
|
|
209
|
+
promise, "initial-link-error", task.getException().getMessage());
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
@ReactMethod
|
|
215
|
+
public void resolveLink(String link, Promise promise) {
|
|
216
|
+
try {
|
|
217
|
+
FirebaseDynamicLinks.getInstance()
|
|
218
|
+
.getDynamicLink(Uri.parse(link))
|
|
219
|
+
.addOnCompleteListener(
|
|
220
|
+
task -> {
|
|
221
|
+
if (task.isSuccessful()) {
|
|
222
|
+
PendingDynamicLinkData linkData = task.getResult();
|
|
223
|
+
// Note: link == null if link invalid, isSuccessful is only false on processing
|
|
224
|
+
// error
|
|
225
|
+
if (linkData != null
|
|
226
|
+
&& linkData.getLink() != null
|
|
227
|
+
&& linkData.getLink().toString() != null) {
|
|
228
|
+
String linkUrl = linkData.getLink().toString();
|
|
229
|
+
int linkMinimumVersion = linkData.getMinimumAppVersion();
|
|
230
|
+
Bundle linkUtmParameters = linkData.getUtmParameters();
|
|
231
|
+
promise.resolve(
|
|
232
|
+
dynamicLinkToWritableMap(
|
|
233
|
+
linkUrl,
|
|
234
|
+
linkMinimumVersion,
|
|
235
|
+
Arguments.makeNativeMap(linkUtmParameters)));
|
|
236
|
+
} else {
|
|
237
|
+
rejectPromiseWithCodeAndMessage(promise, "not-found", "Dynamic link not found");
|
|
238
|
+
}
|
|
239
|
+
} else {
|
|
240
|
+
rejectPromiseWithCodeAndMessage(
|
|
241
|
+
promise, "resolve-link-error", task.getException().getMessage());
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
} catch (Exception e) {
|
|
245
|
+
// This would be very unexpected, but crashing is even less expected
|
|
246
|
+
rejectPromiseWithCodeAndMessage(promise, "resolve-link-error", "Unknown resolve failure");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
private WritableMap dynamicLinkToWritableMap(
|
|
251
|
+
String url, int minVersion, WritableMap utmParameters) {
|
|
252
|
+
WritableMap writableMap = Arguments.createMap();
|
|
253
|
+
|
|
254
|
+
writableMap.putString("url", url);
|
|
255
|
+
|
|
256
|
+
if (minVersion == 0) {
|
|
257
|
+
writableMap.putNull("minimumAppVersion");
|
|
258
|
+
} else {
|
|
259
|
+
writableMap.putInt("minimumAppVersion", minVersion);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
writableMap.putMap("utmParameters", utmParameters);
|
|
263
|
+
|
|
264
|
+
return writableMap;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private DynamicLink.Builder createDynamicLinkBuilder(final ReadableMap dynamicLinkMap) {
|
|
268
|
+
DynamicLink.Builder builder = FirebaseDynamicLinks.getInstance().createDynamicLink();
|
|
269
|
+
|
|
270
|
+
builder.setLink(Uri.parse(dynamicLinkMap.getString("link")));
|
|
271
|
+
builder.setDomainUriPrefix(Objects.requireNonNull(dynamicLinkMap.getString("domainUriPrefix")));
|
|
272
|
+
|
|
273
|
+
if (dynamicLinkMap.hasKey("ios")) {
|
|
274
|
+
buildIosParameters(dynamicLinkMap.getMap("ios"), builder);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (dynamicLinkMap.hasKey("itunes")) {
|
|
278
|
+
buildItunesParameters(dynamicLinkMap.getMap("itunes"), builder);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (dynamicLinkMap.hasKey("social")) {
|
|
282
|
+
buildSocialParameters(dynamicLinkMap.getMap("social"), builder);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (dynamicLinkMap.hasKey("android")) {
|
|
286
|
+
buildAndroidParameters(dynamicLinkMap.getMap("android"), builder);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (dynamicLinkMap.hasKey("analytics")) {
|
|
290
|
+
buildAnalyticsParameters(dynamicLinkMap.getMap("analytics"), builder);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (dynamicLinkMap.hasKey("navigation")) {
|
|
294
|
+
buildNavigationParameters(dynamicLinkMap.getMap("navigation"), builder);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (dynamicLinkMap.hasKey("otherPlatform")) {
|
|
298
|
+
if (dynamicLinkMap.getMap("otherPlatform").hasKey("fallbackUrl")) {
|
|
299
|
+
String OTHER_PLATFORM_LINK_KEY = "ofl";
|
|
300
|
+
String linkUrl = String.valueOf(builder.buildDynamicLink().getUri());
|
|
301
|
+
linkUrl +=
|
|
302
|
+
'&'
|
|
303
|
+
+ OTHER_PLATFORM_LINK_KEY
|
|
304
|
+
+ '='
|
|
305
|
+
+ dynamicLinkMap.getMap("otherPlatform").getString("fallbackUrl");
|
|
306
|
+
builder.setLongLink(Uri.parse(linkUrl));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return builder;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
private void buildAnalyticsParameters(
|
|
314
|
+
@Nullable ReadableMap analyticsMap, DynamicLink.Builder builder) {
|
|
315
|
+
if (analyticsMap == null) return;
|
|
316
|
+
DynamicLink.GoogleAnalyticsParameters.Builder analyticsBuilder =
|
|
317
|
+
new DynamicLink.GoogleAnalyticsParameters.Builder();
|
|
318
|
+
|
|
319
|
+
if (analyticsMap.hasKey("campaign")) {
|
|
320
|
+
analyticsBuilder.setCampaign(analyticsMap.getString("campaign"));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (analyticsMap.hasKey("content")) {
|
|
324
|
+
analyticsBuilder.setContent(analyticsMap.getString("content"));
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (analyticsMap.hasKey("medium")) {
|
|
328
|
+
analyticsBuilder.setMedium(analyticsMap.getString("medium"));
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (analyticsMap.hasKey("source")) {
|
|
332
|
+
analyticsBuilder.setSource(analyticsMap.getString("source"));
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (analyticsMap.hasKey("term")) {
|
|
336
|
+
analyticsBuilder.setTerm(analyticsMap.getString("term"));
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
builder.setGoogleAnalyticsParameters(analyticsBuilder.build());
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
private void buildAndroidParameters(
|
|
343
|
+
@Nullable ReadableMap androidMap, DynamicLink.Builder builder) {
|
|
344
|
+
if (androidMap == null) return;
|
|
345
|
+
DynamicLink.AndroidParameters.Builder androidBuilder =
|
|
346
|
+
new DynamicLink.AndroidParameters.Builder(
|
|
347
|
+
Objects.requireNonNull(androidMap.getString("packageName")));
|
|
348
|
+
|
|
349
|
+
if (androidMap.hasKey("fallbackUrl")) {
|
|
350
|
+
androidBuilder.setFallbackUrl(Uri.parse(androidMap.getString("fallbackUrl")));
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (androidMap.hasKey("minimumVersion")) {
|
|
354
|
+
androidBuilder.setMinimumVersion(
|
|
355
|
+
Integer.parseInt(Objects.requireNonNull(androidMap.getString("minimumVersion"))));
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
builder.setAndroidParameters(androidBuilder.build());
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
private void buildIosParameters(@Nullable ReadableMap iosMap, DynamicLink.Builder builder) {
|
|
362
|
+
if (iosMap == null) return;
|
|
363
|
+
|
|
364
|
+
DynamicLink.IosParameters.Builder iosBuilder =
|
|
365
|
+
new DynamicLink.IosParameters.Builder(Objects.requireNonNull(iosMap.getString("bundleId")));
|
|
366
|
+
|
|
367
|
+
if (iosMap.hasKey("appStoreId")) {
|
|
368
|
+
iosBuilder.setAppStoreId(iosMap.getString("appStoreId"));
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (iosMap.hasKey("customScheme")) {
|
|
372
|
+
iosBuilder.setCustomScheme(iosMap.getString("customScheme"));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (iosMap.hasKey("fallbackUrl")) {
|
|
376
|
+
iosBuilder.setFallbackUrl(Uri.parse(iosMap.getString("fallbackUrl")));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (iosMap.hasKey("iPadBundleId")) {
|
|
380
|
+
iosBuilder.setIpadBundleId(iosMap.getString("iPadBundleId"));
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (iosMap.hasKey("iPadFallbackUrl")) {
|
|
384
|
+
iosBuilder.setIpadFallbackUrl(Uri.parse(iosMap.getString("iPadFallbackUrl")));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (iosMap.hasKey("minimumVersion")) {
|
|
388
|
+
iosBuilder.setMinimumVersion(iosMap.getString("minimumVersion"));
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
builder.setIosParameters(iosBuilder.build());
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
private void buildItunesParameters(@Nullable ReadableMap iTunesMap, DynamicLink.Builder builder) {
|
|
395
|
+
if (iTunesMap == null) return;
|
|
396
|
+
DynamicLink.ItunesConnectAnalyticsParameters.Builder iTunesBuilder =
|
|
397
|
+
new DynamicLink.ItunesConnectAnalyticsParameters.Builder();
|
|
398
|
+
|
|
399
|
+
if (iTunesMap.hasKey("affiliateToken")) {
|
|
400
|
+
iTunesBuilder.setAffiliateToken(iTunesMap.getString("affiliateToken"));
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (iTunesMap.hasKey("campaignToken")) {
|
|
404
|
+
iTunesBuilder.setCampaignToken(iTunesMap.getString("campaignToken"));
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (iTunesMap.hasKey("providerToken")) {
|
|
408
|
+
iTunesBuilder.setProviderToken(iTunesMap.getString("providerToken"));
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
builder.setItunesConnectAnalyticsParameters(iTunesBuilder.build());
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
private void buildNavigationParameters(
|
|
415
|
+
@Nullable ReadableMap navigationMap, DynamicLink.Builder builder) {
|
|
416
|
+
if (navigationMap == null) return;
|
|
417
|
+
DynamicLink.NavigationInfoParameters.Builder navigationBuilder =
|
|
418
|
+
new DynamicLink.NavigationInfoParameters.Builder();
|
|
419
|
+
|
|
420
|
+
if (navigationMap.hasKey("forcedRedirectEnabled")) {
|
|
421
|
+
navigationBuilder.setForcedRedirectEnabled(navigationMap.getBoolean("forcedRedirectEnabled"));
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
builder.setNavigationInfoParameters(navigationBuilder.build());
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
private void buildSocialParameters(@Nullable ReadableMap socialMap, DynamicLink.Builder builder) {
|
|
428
|
+
if (socialMap == null) return;
|
|
429
|
+
DynamicLink.SocialMetaTagParameters.Builder socialBuilder =
|
|
430
|
+
new DynamicLink.SocialMetaTagParameters.Builder();
|
|
431
|
+
|
|
432
|
+
if (socialMap.hasKey("descriptionText")) {
|
|
433
|
+
socialBuilder.setDescription(socialMap.getString("descriptionText"));
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (socialMap.hasKey("imageUrl")) {
|
|
437
|
+
socialBuilder.setImageUrl(Uri.parse(socialMap.getString("imageUrl")));
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (socialMap.hasKey("title")) {
|
|
441
|
+
socialBuilder.setTitle(socialMap.getString("title"));
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
builder.setSocialMetaTagParameters(socialBuilder.build());
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
@Override
|
|
448
|
+
public void onHostDestroy() {
|
|
449
|
+
initialLinkUrl = null;
|
|
450
|
+
gotInitialLink = false;
|
|
451
|
+
initialLinkMinimumVersion = 0;
|
|
452
|
+
launchedFromHistory = false;
|
|
453
|
+
initialPromise = null;
|
|
454
|
+
hostResumed = false;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
@Override
|
|
458
|
+
public void onNewIntent(Intent intent) {
|
|
459
|
+
FirebaseDynamicLinks.getInstance()
|
|
460
|
+
.getDynamicLink(intent)
|
|
461
|
+
.addOnCompleteListener(
|
|
462
|
+
task -> {
|
|
463
|
+
if (task.isSuccessful()) {
|
|
464
|
+
PendingDynamicLinkData pendingDynamicLinkData = task.getResult();
|
|
465
|
+
if (pendingDynamicLinkData != null) {
|
|
466
|
+
ReactNativeFirebaseEventEmitter.getSharedInstance()
|
|
467
|
+
.sendEvent(
|
|
468
|
+
new ReactNativeFirebaseEvent(
|
|
469
|
+
"dynamic_links_link_received",
|
|
470
|
+
dynamicLinkToWritableMap(
|
|
471
|
+
pendingDynamicLinkData.getLink().toString(),
|
|
472
|
+
pendingDynamicLinkData.getMinimumAppVersion(),
|
|
473
|
+
Arguments.makeNativeMap(
|
|
474
|
+
pendingDynamicLinkData.getUtmParameters()))));
|
|
475
|
+
}
|
|
476
|
+
} else {
|
|
477
|
+
Log.e(
|
|
478
|
+
TAG,
|
|
479
|
+
"RNFB: An unknown exception occurred calling getDynamicLink",
|
|
480
|
+
task.getException());
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
@Override
|
|
486
|
+
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {}
|
|
487
|
+
|
|
488
|
+
@Override
|
|
489
|
+
public void onHostResume() {
|
|
490
|
+
// Flag state is resumed.
|
|
491
|
+
hostResumed = true;
|
|
492
|
+
// Check if getInitialLink was called before LifeCycleState was RESUMED
|
|
493
|
+
// and there's a pending Promise.
|
|
494
|
+
if (initialPromise != null) {
|
|
495
|
+
// Call getInitialLink getInitialLink with the Promise that was passed in the original call.
|
|
496
|
+
getInitialLink(initialPromise);
|
|
497
|
+
// Clear the Promise
|
|
498
|
+
initialPromise = null;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
@Override
|
|
503
|
+
public void onHostPause() {
|
|
504
|
+
// Flag state is not resumed.
|
|
505
|
+
hostResumed = false;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
package io.invertase.firebase.dynamiclinks;
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this library except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import com.facebook.react.ReactPackage;
|
|
21
|
+
import com.facebook.react.bridge.NativeModule;
|
|
22
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
23
|
+
import com.facebook.react.uimanager.ViewManager;
|
|
24
|
+
import java.util.ArrayList;
|
|
25
|
+
import java.util.Collections;
|
|
26
|
+
import java.util.List;
|
|
27
|
+
import javax.annotation.Nonnull;
|
|
28
|
+
|
|
29
|
+
@SuppressWarnings("unused")
|
|
30
|
+
public class ReactNativeFirebaseDynamicLinksPackage implements ReactPackage {
|
|
31
|
+
@Nonnull
|
|
32
|
+
@Override
|
|
33
|
+
public List<NativeModule> createNativeModules(@Nonnull ReactApplicationContext reactContext) {
|
|
34
|
+
List<NativeModule> modules = new ArrayList<>();
|
|
35
|
+
modules.add(new ReactNativeFirebaseDynamicLinksModule(reactContext));
|
|
36
|
+
return modules;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Nonnull
|
|
40
|
+
@Override
|
|
41
|
+
public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
|
|
42
|
+
return Collections.emptyList();
|
|
43
|
+
}
|
|
44
|
+
}
|
package/app.plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./plugin/build');
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#import <Foundation/Foundation.h>
|
|
19
|
+
#import <UIKit/UIKit.h>
|
|
20
|
+
|
|
21
|
+
#import <Firebase/Firebase.h>
|
|
22
|
+
|
|
23
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
24
|
+
|
|
25
|
+
static NSString *const LINK_RECEIVED_EVENT = @"dynamic_links_link_received";
|
|
26
|
+
|
|
27
|
+
@interface RNFBDynamicLinksAppDelegateInterceptor : NSObject <UIApplicationDelegate>
|
|
28
|
+
@property(strong, readwrite) NSString *_Nullable initialLinkUrl;
|
|
29
|
+
@property(strong, readwrite) NSString *_Nullable initialLinkMinimumAppVersion;
|
|
30
|
+
@property(strong, readwrite)
|
|
31
|
+
NSDictionary<NSString *, id> *_Nonnull initialLinkUtmParametersDictionary;
|
|
32
|
+
|
|
33
|
+
+ (instancetype)sharedInstance;
|
|
34
|
+
|
|
35
|
+
@end
|
|
36
|
+
|
|
37
|
+
NS_ASSUME_NONNULL_END
|