commit
101a426307
|
@ -90,4 +90,5 @@ dependencies {
|
|||
compile "com.google.firebase:firebase-perf:$firebaseVersion"
|
||||
compile "com.google.firebase:firebase-ads:$firebaseVersion"
|
||||
compile "com.google.firebase:firebase-firestore:$firebaseVersion"
|
||||
compile "com.google.firebase:firebase-invites:$firebaseVersion"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,284 @@
|
|||
package io.invertase.firebase.links;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.facebook.react.bridge.ActivityEventListener;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
||||
import com.google.firebase.dynamiclinks.DynamicLink;
|
||||
import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
|
||||
import com.google.firebase.dynamiclinks.ShortDynamicLink;
|
||||
import com.google.firebase.dynamiclinks.PendingDynamicLinkData;
|
||||
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import com.google.android.gms.tasks.OnCompleteListener;
|
||||
import com.google.android.gms.tasks.OnSuccessListener;
|
||||
import com.google.android.gms.tasks.OnFailureListener;
|
||||
|
||||
import io.invertase.firebase.Utils;
|
||||
|
||||
public class RNFirebaseLinks extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener {
|
||||
private final static String TAG = RNFirebaseLinks.class.getCanonicalName();
|
||||
private String mInitialLink = null;
|
||||
private boolean mInitialLinkInitialized = false;
|
||||
|
||||
private interface ResolveHandler {
|
||||
void onResolved(String url);
|
||||
}
|
||||
|
||||
private interface ErrorHandler {
|
||||
void onError(Exception e);
|
||||
}
|
||||
|
||||
public RNFirebaseLinks(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
getReactApplicationContext().addActivityEventListener(this);
|
||||
getReactApplicationContext().addLifecycleEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "RNFirebaseLinks";
|
||||
}
|
||||
|
||||
|
||||
private void resolveLink(Intent intent, final ResolveHandler resolveHandler, final ErrorHandler errorHandler) {
|
||||
FirebaseDynamicLinks.getInstance()
|
||||
.getDynamicLink(intent)
|
||||
.addOnSuccessListener(new OnSuccessListener<PendingDynamicLinkData>() {
|
||||
@Override
|
||||
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
|
||||
if (pendingDynamicLinkData != null) {
|
||||
Uri deepLinkUri = pendingDynamicLinkData.getLink();
|
||||
String url = deepLinkUri.toString();
|
||||
resolveHandler.onResolved(url);
|
||||
} else {
|
||||
resolveHandler.onResolved(null);
|
||||
}
|
||||
}
|
||||
})
|
||||
.addOnFailureListener(new OnFailureListener() {
|
||||
@Override
|
||||
public void onFailure(@NonNull Exception e) {
|
||||
errorHandler.onError(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getInitialLink(final Promise promise) {
|
||||
if (mInitialLinkInitialized) {
|
||||
promise.resolve(mInitialLink);
|
||||
} else {
|
||||
Activity activity = getCurrentActivity();
|
||||
if (activity != null) {
|
||||
resolveLink(activity.getIntent(), new ResolveHandler() {
|
||||
@Override
|
||||
public void onResolved(String url) {
|
||||
if (url != null) {
|
||||
mInitialLink = url;
|
||||
Log.d(TAG, "getInitialLink received a new dynamic link from pendingDynamicLinkData");
|
||||
}
|
||||
Log.d(TAG, "initial link is: " + mInitialLink);
|
||||
promise.resolve(mInitialLink);
|
||||
mInitialLinkInitialized = true;
|
||||
}
|
||||
}, new ErrorHandler() {
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
Log.e(TAG, "getInitialLink: failed to resolve link", e);
|
||||
promise.reject("links/getDynamicLink", e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.d(TAG, "getInitialLink: activity is null");
|
||||
promise.resolve(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
|
||||
// Not required for this module
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
resolveLink(intent, new ResolveHandler() {
|
||||
@Override
|
||||
public void onResolved(String url) {
|
||||
if (url != null) {
|
||||
Log.d(TAG, "handleLink: sending link: " + url);
|
||||
Utils.sendEvent(getReactApplicationContext(), "dynamic_link_received", url);
|
||||
}
|
||||
}
|
||||
}, new ErrorHandler() {
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
Log.e(TAG, "handleLink: failed to resolve link", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostResume() {
|
||||
// Not required for this module
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostPause() {
|
||||
// Not required for this module
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {
|
||||
mInitialLink = null;
|
||||
mInitialLinkInitialized = false;
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void createDynamicLink(final ReadableMap parameters, final Promise promise) {
|
||||
try {
|
||||
Map<String, Object> metaData = Utils.recursivelyDeconstructReadableMap(parameters);
|
||||
|
||||
DynamicLink.Builder builder = getDynamicLinkBuilderFromMap(metaData);
|
||||
Uri link = builder.buildDynamicLink().getUri();
|
||||
|
||||
Log.d(TAG, "created dynamic link: " + link.toString());
|
||||
promise.resolve(link.toString());
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "create dynamic link failure " + ex.getMessage());
|
||||
promise.reject("links/failure", ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void createShortDynamicLink(final ReadableMap parameters, final Promise promise) {
|
||||
try {
|
||||
Map<String, Object> metaData = Utils.recursivelyDeconstructReadableMap(parameters);
|
||||
|
||||
DynamicLink.Builder builder = getDynamicLinkBuilderFromMap(metaData);
|
||||
|
||||
Task<ShortDynamicLink> shortLinkTask = getShortDynamicLinkTask(builder, metaData)
|
||||
.addOnCompleteListener(new OnCompleteListener<ShortDynamicLink>() {
|
||||
@Override
|
||||
public void onComplete(@NonNull Task<ShortDynamicLink> task) {
|
||||
if (task.isSuccessful()) {
|
||||
Uri shortLink = task.getResult().getShortLink();
|
||||
Log.d(TAG, "created short dynamic link: " + shortLink.toString());
|
||||
promise.resolve(shortLink.toString());
|
||||
} else {
|
||||
Log.e(TAG, "create short dynamic link failure " + task.getException().getMessage());
|
||||
promise.reject("links/failure", task.getException().getMessage(), task.getException());
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "create short dynamic link failure " + ex.getMessage());
|
||||
promise.reject("links/failure", ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private DynamicLink.Builder getDynamicLinkBuilderFromMap(final Map<String, Object> metaData) {
|
||||
DynamicLink.Builder parametersBuilder = FirebaseDynamicLinks.getInstance().createDynamicLink();
|
||||
try {
|
||||
parametersBuilder.setLink(Uri.parse((String) metaData.get("link")));
|
||||
parametersBuilder.setDynamicLinkDomain((String) metaData.get("dynamicLinkDomain"));
|
||||
setAndroidParameters(metaData, parametersBuilder);
|
||||
setIosParameters(metaData, parametersBuilder);
|
||||
setSocialMetaTagParameters(metaData, parametersBuilder);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "error while building parameters " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
return parametersBuilder;
|
||||
}
|
||||
|
||||
private Task<ShortDynamicLink> getShortDynamicLinkTask(final DynamicLink.Builder builder, final Map<String, Object> metaData) {
|
||||
Map<String, Object> suffix = (Map<String, Object>) metaData.get("suffix");
|
||||
if (suffix != null) {
|
||||
String option = (String) suffix.get("option");
|
||||
if ("SHORT".equals(option)) {
|
||||
return builder.buildShortDynamicLink(ShortDynamicLink.Suffix.SHORT);
|
||||
} else if ("UNGUESSABLE".equals(option)) {
|
||||
return builder.buildShortDynamicLink(ShortDynamicLink.Suffix.UNGUESSABLE);
|
||||
}
|
||||
}
|
||||
return builder.buildShortDynamicLink();
|
||||
}
|
||||
|
||||
|
||||
private void setAndroidParameters(final Map<String, Object> metaData, final DynamicLink.Builder parametersBuilder) {
|
||||
Map<String, Object> androidParameters = (Map<String, Object>) metaData.get("androidInfo");
|
||||
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")) {
|
||||
androidParametersBuilder.setMinimumVersion(Integer.parseInt((String) androidParameters.get("androidMinPackageVersionCode")));
|
||||
}
|
||||
parametersBuilder.setAndroidParameters(androidParametersBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
private void setIosParameters(final Map<String, Object> metaData, final DynamicLink.Builder parametersBuilder) {
|
||||
Map<String, Object> iosParameters = (Map<String, Object>) metaData.get("iosInfo");
|
||||
if (iosParameters != null) {
|
||||
DynamicLink.IosParameters.Builder iosParametersBuilder =
|
||||
new DynamicLink.IosParameters.Builder((String) iosParameters.get("iosBundleId"));
|
||||
|
||||
if (iosParameters.containsKey("iosAppStoreId")) {
|
||||
iosParametersBuilder.setAppStoreId((String) iosParameters.get("iosAppStoreId"));
|
||||
}
|
||||
if (iosParameters.containsKey("iosCustomScheme")) {
|
||||
iosParametersBuilder.setCustomScheme((String) iosParameters.get("iosCustomScheme"));
|
||||
}
|
||||
if (iosParameters.containsKey("iosFallbackLink")) {
|
||||
iosParametersBuilder.setFallbackUrl(Uri.parse((String) iosParameters.get("iosFallbackLink")));
|
||||
}
|
||||
if (iosParameters.containsKey("iosIpadBundleId")) {
|
||||
iosParametersBuilder.setIpadBundleId((String) iosParameters.get("iosIpadBundleId"));
|
||||
}
|
||||
if (iosParameters.containsKey("iosIpadFallbackLink")) {
|
||||
iosParametersBuilder.setIpadFallbackUrl(Uri.parse((String) iosParameters.get("iosIpadFallbackLink")));
|
||||
}
|
||||
if (iosParameters.containsKey("iosMinPackageVersionCode")) {
|
||||
iosParametersBuilder.setMinimumVersion((String) iosParameters.get("iosMinPackageVersionCode"));
|
||||
}
|
||||
parametersBuilder.setIosParameters(iosParametersBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
private void setSocialMetaTagParameters(final Map<String, Object> metaData, final DynamicLink.Builder parametersBuilder) {
|
||||
Map<String, Object> socialMetaTagParameters = (Map<String, Object>) metaData.get("socialMetaTagInfo");
|
||||
if (socialMetaTagParameters != null) {
|
||||
DynamicLink.SocialMetaTagParameters.Builder socialMetaTagParametersBuilder =
|
||||
new DynamicLink.SocialMetaTagParameters.Builder();
|
||||
|
||||
if (socialMetaTagParameters.containsKey("socialDescription")) {
|
||||
socialMetaTagParametersBuilder.setDescription((String) socialMetaTagParameters.get("socialDescription"));
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package io.invertase.firebase.links;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class RNFirebaseLinksPackage implements ReactPackage {
|
||||
public RNFirebaseLinksPackage() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reactContext react application context that can be used to create modules
|
||||
* @return list of native modules to register with the newly created catalyst instance
|
||||
*/
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
modules.add(new RNFirebaseLinks(reactContext));
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reactContext
|
||||
* @return a list of view managers that should be registered with {@link UIManagerModule}
|
||||
*/
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ All in all, RNFirebase provides much faster performance (~2x) over the web SDK a
|
|||
| _-- Multiple Apps_ | ❌ | ❌ | ✅ | ✅ |
|
||||
| **Cloud Messaging (FCM)** | ✅ | ✅ | ✅ |**?**|
|
||||
| **Crash Reporting** | ✅ | ✅ | ✅ | ❌ |
|
||||
| **Dynamic Links** | ❌ | ❌ | ❌ | ❌ |
|
||||
| **Dynamic Links** | ❌ | ❌ | ✅ | ❌ |
|
||||
| **Firestore** | ❌ | ❌ | ✅ | ❌ |
|
||||
| **Invites** | ❌ | ❌ | ❌ | ❌ |
|
||||
| **Performance Monitoring** | ✅ | ✅ | ✅ | ❌ |
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
- [Cloud Messaging](/modules/cloud-messaging)
|
||||
- [Crash Reporting](/modules/crash)
|
||||
- [Database](/modules/database)
|
||||
- [Dynamic Links](/modules/links)
|
||||
- [Firestore (Beta)](/modules/firestore)
|
||||
- [Remote Config](/modules/config)
|
||||
- [Storage](/modules/storage)
|
||||
|
|
|
@ -49,6 +49,7 @@ dependencies {
|
|||
compile "com.google.firebase:firebase-crash:11.4.2"
|
||||
compile "com.google.firebase:firebase-database:11.4.2"
|
||||
compile "com.google.firebase:firebase-firestore:11.4.2"
|
||||
compile "com.google.firebase:firebase-invites:11.4.2"
|
||||
compile "com.google.firebase:firebase-messaging:11.4.2"
|
||||
compile "com.google.firebase:firebase-perf:11.4.2"
|
||||
compile "com.google.firebase:firebase-storage:11.4.2"
|
||||
|
@ -97,6 +98,7 @@ import io.invertase.firebase.config.RNFirebaseRemoteConfigPackage; // Firebase R
|
|||
import io.invertase.firebase.crash.RNFirebaseCrashPackage; // Firebase Crash Reporting
|
||||
import io.invertase.firebase.database.RNFirebaseDatabasePackage; // Firebase Realtime Database
|
||||
import io.invertase.firebase.firestore.RNFirebaseFirestorePackage; // Firebase Firestore
|
||||
import io.invertase.firebase.links.RNFirebaseLinksPackage; // Firebase Links
|
||||
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage; // Firebase Cloud Messaging
|
||||
import io.invertase.firebase.perf.RNFirebasePerformancePackage; // Firebase Performance
|
||||
import io.invertase.firebase.storage.RNFirebaseStoragePackage; // Firebase Storage
|
||||
|
@ -117,6 +119,7 @@ public class MainApplication extends Application implements ReactApplication {
|
|||
new RNFirebaseCrashPackage(),
|
||||
new RNFirebaseDatabasePackage(),
|
||||
new RNFirebaseFirestorePackage(),
|
||||
new RNFirebaseLinksPackage(),
|
||||
new RNFirebaseMessagingPackage(),
|
||||
new RNFirebasePerformancePackage(),
|
||||
new RNFirebaseStoragePackage()
|
||||
|
@ -206,3 +209,22 @@ dependencies {
|
|||
compile "com.google.firebase:firebase-perf:11.4.2"
|
||||
}
|
||||
```
|
||||
|
||||
## 7) Dynamic Links (optional)
|
||||
|
||||
If you plan on using [Firebase Dynamic
|
||||
Links](https://firebase.google.com/docs/dynamic-links/):
|
||||
|
||||
Make sure to setup dynamic links for Android as described [here](https://firebase.google.com/docs/dynamic-links/android/receive#set-up-firebase-and-the-dynamic-links-sdk)
|
||||
|
||||
In `android/app/src/main/AndroidManifest.xml`, add a new intent filter to the activity that handles deep links for your app (for react-native this is usually MainActivity), and specify the host and the scheme:
|
||||
|
||||
```xml
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<data android:host="yoursite.example.com" android:scheme="http"/>
|
||||
<data android:host="yoursite.example.com" android:scheme="https"/>
|
||||
</intent-filter>
|
||||
```
|
||||
|
|
|
@ -168,3 +168,72 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
|||
If you're having problems with messages not being received, check out the following blog post for help:
|
||||
|
||||
https://firebase.googleblog.com/2017/01/debugging-firebase-cloud-messaging-on.html
|
||||
|
||||
|
||||
|
||||
## 5) Dynamic Links (optional)
|
||||
|
||||
If you plan on using [Firebase Dynamic Links](https://firebase.google.com/docs/dynamic-links/) then, you need to:
|
||||
|
||||
### 5.1) Setup
|
||||
|
||||
Make sure to setup dynamic links for iOS as described [here](https://firebase.google.com/docs/dynamic-links/ios/receive#set-up-firebase-and-the-dynamic-links-sdk)
|
||||
|
||||
### 5.2) create a new URL type
|
||||
|
||||
In the Info tab of your app's Xcode project, create a new URL type to be used for Dynamic Links. Set the Identifier field to a unique value and the URL scheme field to either your bundle identifier or a unique value.
|
||||
|
||||
### 5.3) Enable Associated Domains capability
|
||||
|
||||
In the Capabilities tab of your app's Xcode project, enable Associated Domains and
|
||||
add the following to the Associated Domains list:
|
||||
`applinks:app_code.app.goo.gl` where `app_code` is your dynamic links domain application code.
|
||||
|
||||
### 5.4) Update `AppDelegate.m`
|
||||
|
||||
Add the following import:
|
||||
|
||||
`#import "RNFirebaseLinks.h"`
|
||||
|
||||
Add the following to the `didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` method before `[FIRApp Configure]`:
|
||||
|
||||
`[FIROptions defaultOptions].deepLinkURLScheme = CUSTOM_URL_SCHEME;`
|
||||
where `CUSTOM_URL_SCHEME` is the custom URL scheme you defined in your Xcode project.
|
||||
|
||||
In the application:openURL:sourceApplication:annotation: (for iOS 8 and older) add the following:
|
||||
|
||||
```objectivec
|
||||
- (BOOL)application:(UIApplication *)app
|
||||
openURL:(NSURL *)url
|
||||
options:(NSDictionary<NSString *, id> *)options {
|
||||
return [RNFirebaseLinks application:application
|
||||
openURL:url
|
||||
options:options];
|
||||
}
|
||||
```
|
||||
|
||||
In the application:openURL:options: (for iOS 9) add the following:
|
||||
|
||||
```objectivec
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation {
|
||||
return [RNFirebaseLinks application:application
|
||||
openURL:url
|
||||
sourceApplication:sourceApplication
|
||||
annotation:annotation];
|
||||
}
|
||||
```
|
||||
|
||||
In the application:continueUserActivity:restorationHandler (Universal Links on iOS 9 and newer) add the following:
|
||||
|
||||
```objectivec
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray *))restorationHandler {
|
||||
return [RNFirebaseLinks application:application
|
||||
continueUserActivity:userActivity
|
||||
restorationHandler:restorationHandler];
|
||||
}
|
||||
```
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
# Dynamic Links
|
||||
|
||||
[Firebase Dynamic Links](https://firebase.google.com/docs/dynamic-links/) allows you to create and receive links on both Android and iOS platforms. Assuming the installation instructions have been followed, Firebase Dynamic Links is ready to go.
|
||||
|
||||
|
||||
All Dynamic Links operations are accessed via `firebase.links()`
|
||||
|
||||
## Create Dynamic Links
|
||||
|
||||
RNFirebase mimics [Firebase's REST API](https://firebase.google.com/docs/dynamic-links/rest) for Dynamic Links creation.
|
||||
The differences from the REST API are:
|
||||
1. The input for the methods is a javascript object instead of a JSON object.
|
||||
2. The response contains the URL string only.
|
||||
3. There is no `dynamicLinkInfo` element. Instead, all of the elements under it were moved to be under the top-level.
|
||||
|
||||
### Methods
|
||||
|
||||
#### `createDynamicLink(parameters: Object): Promise<String>`
|
||||
|
||||
Creates a long dynamic link.
|
||||
|
||||
```javascript
|
||||
firebase.links().createDynamicLink({
|
||||
dynamicLinkDomain: "abc123.app.goo.gl",
|
||||
link: "https://example.com?param1=foo¶m2=bar",
|
||||
androidInfo: {
|
||||
androidPackageName: "com.example.android"
|
||||
},
|
||||
iosInfo: {
|
||||
iosBundleId: "com.example.ios"
|
||||
}
|
||||
}).
|
||||
then((url) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
#### `createShortDynamicLink(parameters: Object): Promise<String>`
|
||||
|
||||
Creates a short dynamic link.
|
||||
|
||||
```javascript
|
||||
firebase.links().createShortDynamicLink({
|
||||
dynamicLinkDomain: "abc123.app.goo.gl",
|
||||
link: "https://example.com?param1=foo¶m2=bar",
|
||||
androidInfo: {
|
||||
androidPackageName: "com.example.android"
|
||||
},
|
||||
iosInfo: {
|
||||
iosBundleId: "com.example.ios"
|
||||
}
|
||||
}).
|
||||
then((url) => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
### Parameters
|
||||
|
||||
Only the following parameters are currently supported:
|
||||
|
||||
```javascript
|
||||
{
|
||||
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',
|
||||
},
|
||||
}
|
||||
```
|
||||
**please note:**
|
||||
1. dynamicLinkDomain and link are mandatory fields. In addition, when using `androidInfo` or `iosInfo`, `androidPackageName` and `iosBundleId` are mandatory (respectively).
|
||||
2. In oppose to the REST API, There is no `dynamicLinkInfo` element. Instead, all of the elements under it were moved to be under the top-level.
|
||||
|
||||
For more information [see reference](https://firebase.google.com/docs/reference/dynamic-links/link-shortener)
|
||||
|
||||
## Receive Dynamic Links
|
||||
|
||||
### Methods
|
||||
|
||||
#### `getInitialLink(): Promise<String>`
|
||||
|
||||
Call getInitialLink to access the URL that the app has been launched from. If the app was not launched from a URL, the return value is null.
|
||||
|
||||
```javascript
|
||||
firebase.links().getInitialLink().then((url) => {
|
||||
//...
|
||||
});
|
||||
```
|
||||
|
||||
#### `onLink(listener: Function<String>): Function`
|
||||
|
||||
On a new URL, the payload URL is passed to the listener callback. This method is only triggered when the app is running. Use getInitialLink for URLs which cause the app to open.
|
||||
In order to subscribe to the listener, call to the method with a callback and save the returned function.
|
||||
When you want to unsubscribe, just call the function that returned at subscription.
|
||||
|
||||
```javascript
|
||||
// Subscribe
|
||||
const unsubscribe = firebase.links().onLink((url) => {
|
||||
//...
|
||||
});
|
||||
|
||||
// Unsubscribe
|
||||
unsubscribe();
|
||||
```
|
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
17AF4F6B1F59CDBF00C02336 /* RNFirebaseLinks.m in Sources */ = {isa = PBXBuildFile; fileRef = 17AF4F6A1F59CDBF00C02336 /* RNFirebaseLinks.m */; };
|
||||
8300A7AE1F31E143001B16AB /* RNFirebaseDatabaseReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8300A7AD1F31E143001B16AB /* RNFirebaseDatabaseReference.m */; };
|
||||
8323CF061F6FBD870071420B /* BannerComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CEFF1F6FBD870071420B /* BannerComponent.m */; };
|
||||
8323CF071F6FBD870071420B /* NativeExpressComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF011F6FBD870071420B /* NativeExpressComponent.m */; };
|
||||
|
@ -43,6 +44,8 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
134814201AA4EA6300B7C361 /* libRNFirebase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFirebase.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
17AF4F691F59CDBF00C02336 /* RNFirebaseLinks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseLinks.h; sourceTree = "<group>"; };
|
||||
17AF4F6A1F59CDBF00C02336 /* RNFirebaseLinks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseLinks.m; sourceTree = "<group>"; };
|
||||
8300A7AC1F31E143001B16AB /* RNFirebaseDatabaseReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseDatabaseReference.h; sourceTree = "<group>"; };
|
||||
8300A7AD1F31E143001B16AB /* RNFirebaseDatabaseReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseDatabaseReference.m; sourceTree = "<group>"; };
|
||||
8323CEFE1F6FBD870071420B /* BannerComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BannerComponent.h; sourceTree = "<group>"; };
|
||||
|
@ -105,9 +108,20 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
17AF4F681F59CDBF00C02336 /* links */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
17AF4F691F59CDBF00C02336 /* RNFirebaseLinks.h */,
|
||||
17AF4F6A1F59CDBF00C02336 /* RNFirebaseLinks.m */,
|
||||
);
|
||||
name = links;
|
||||
path = RNFirebase/links;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58B511D21A9E6C8500147676 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
17AF4F681F59CDBF00C02336 /* links */,
|
||||
839D914D1EF3E20A0077C7C8 /* admob */,
|
||||
839D91541EF3E20A0077C7C8 /* analytics */,
|
||||
839D91571EF3E20A0077C7C8 /* auth */,
|
||||
|
@ -117,11 +131,11 @@
|
|||
8376F70D1F7C141500D45A85 /* firestore */,
|
||||
839D91631EF3E20A0077C7C8 /* messaging */,
|
||||
839D91661EF3E20A0077C7C8 /* perf */,
|
||||
839D91691EF3E20A0077C7C8 /* storage */,
|
||||
134814211AA4EA7D00B7C361 /* Products */,
|
||||
D950369C1D19C77400F7094D /* RNFirebase.h */,
|
||||
D950369D1D19C77400F7094D /* RNFirebase.m */,
|
||||
839D91771EF3E22F0077C7C8 /* RNFirebaseEvents.h */,
|
||||
134814211AA4EA7D00B7C361 /* Products */,
|
||||
839D91691EF3E20A0077C7C8 /* storage */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
@ -301,6 +315,7 @@
|
|||
files = (
|
||||
839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */,
|
||||
839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */,
|
||||
17AF4F6B1F59CDBF00C02336 /* RNFirebaseLinks.m in Sources */,
|
||||
8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */,
|
||||
839D91761EF3E20B0077C7C8 /* RNFirebaseStorage.m in Sources */,
|
||||
8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */,
|
||||
|
|
|
@ -39,4 +39,7 @@ static NSString *const MESSAGING_NOTIFICATION_RECEIVED = @"messaging_notificatio
|
|||
static NSString *const ADMOB_INTERSTITIAL_EVENT = @"interstitial_event";
|
||||
static NSString *const ADMOB_REWARDED_VIDEO_EVENT = @"rewarded_video_event";
|
||||
|
||||
// Links
|
||||
static NSString *const LINKS_DYNAMIC_LINK_RECEIVED = @"dynamic_link_received";
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef RNFirebaseLinks_h
|
||||
#define RNFirebaseLinks_h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if __has_include(<FirebaseDynamicLinks/FIRDynamicLinks.h>)
|
||||
#import <Firebase.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
@interface RNFirebaseLinks : RCTEventEmitter<RCTBridgeModule> {
|
||||
|
||||
}
|
||||
+ (BOOL)application:(UIApplication *)app
|
||||
openURL:(NSURL *)url
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;
|
||||
|
||||
+ (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation;
|
||||
|
||||
+ (BOOL)application:(UIApplication *)application
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray *))restorationHandler;
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@interface RNFirebaseLinks : NSObject
|
||||
@end
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,276 @@
|
|||
#import "RNFirebaseLinks.h"
|
||||
|
||||
#if __has_include(<FirebaseDynamicLinks/FIRDynamicLink.h>)
|
||||
#import "RNFirebaseEvents.h"
|
||||
|
||||
|
||||
static void sendDynamicLink(NSURL *url, id sender) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:LINKS_DYNAMIC_LINK_RECEIVED
|
||||
object:sender
|
||||
userInfo:@{@"url": url.absoluteString}];
|
||||
NSLog(@"sendDynamicLink Success: %@", url.absoluteString);
|
||||
}
|
||||
|
||||
@implementation RNFirebaseLinks
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
NSLog(@"Setting up RNFirebaseLinks instance");
|
||||
[self initialiseLinks];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initialiseLinks {
|
||||
// Set up internal listener to send notification over bridge
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(sendDynamicLinkEvent:)
|
||||
name:LINKS_DYNAMIC_LINK_RECEIVED
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
+ (BOOL)application:(UIApplication *)app
|
||||
openURL:(NSURL *)url
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [self handleLinkFromCustomSchemeURL:url];
|
||||
}
|
||||
|
||||
+ (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation {
|
||||
return [self handleLinkFromCustomSchemeURL:url];
|
||||
}
|
||||
|
||||
+(BOOL)handleLinkFromCustomSchemeURL:(NSURL *)url {
|
||||
FIRDynamicLink *dynamicLink =
|
||||
[[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
|
||||
if (dynamicLink) {
|
||||
sendDynamicLink(dynamicLink.url, self);
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL)application:(UIApplication *)application
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray *))restorationHandler {
|
||||
BOOL handled = [[FIRDynamicLinks dynamicLinks]
|
||||
handleUniversalLink:userActivity.webpageURL
|
||||
completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) {
|
||||
if (error != nil){
|
||||
NSLog(@"Failed to handle universal link: %@", [error localizedDescription]);
|
||||
}
|
||||
else {
|
||||
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
|
||||
NSURL* url = dynamicLink ? dynamicLink.url : userActivity.webpageURL;
|
||||
sendDynamicLink(url, self);
|
||||
}
|
||||
}
|
||||
}];
|
||||
return handled;
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents {
|
||||
return @[LINKS_DYNAMIC_LINK_RECEIVED];
|
||||
}
|
||||
|
||||
- (void)sendDynamicLinkEvent:(NSNotification *)notification {
|
||||
[self sendEventWithName:LINKS_DYNAMIC_LINK_RECEIVED body:notification.userInfo[@"url"]];
|
||||
}
|
||||
|
||||
-(void)handleInitialLinkFromCustomSchemeURL:(NSURL*)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
||||
FIRDynamicLink *dynamicLink =
|
||||
[[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
|
||||
NSString* urlString = dynamicLink ? dynamicLink.url.absoluteString : (id)kCFNull;
|
||||
NSLog(@"initial link is: %@", urlString);
|
||||
resolve(urlString);
|
||||
}
|
||||
|
||||
-(void)handleInitialLinkFromUniversalLinkURL:(NSDictionary *)userActivityDictionary resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
||||
NSUserActivity* userActivity = (NSUserActivity*) userActivityDictionary[@"UIApplicationLaunchOptionsUserActivityKey"];
|
||||
if ([userActivityDictionary[UIApplicationLaunchOptionsUserActivityTypeKey] isEqual:NSUserActivityTypeBrowsingWeb])
|
||||
{
|
||||
[[FIRDynamicLinks dynamicLinks]
|
||||
handleUniversalLink:userActivity.webpageURL
|
||||
completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) {
|
||||
if (error != nil){
|
||||
NSLog(@"Failed to handle universal link: %@", [error localizedDescription]);
|
||||
reject(@"links/failure", @"Failed to handle universal link", error);
|
||||
}
|
||||
else {
|
||||
NSString* urlString = dynamicLink ? dynamicLink.url.absoluteString : userActivity.webpageURL.absoluteString;
|
||||
NSLog(@"initial link is: %@", urlString);
|
||||
resolve(urlString);
|
||||
}
|
||||
}];
|
||||
}
|
||||
else {
|
||||
NSLog(@"no initial link");
|
||||
resolve((id)kCFNull);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getInitialLink:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) {
|
||||
NSURL* url = (NSURL*)self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey];
|
||||
[self handleInitialLinkFromCustomSchemeURL:url resolver:resolve rejecter:reject];
|
||||
|
||||
} else {
|
||||
NSDictionary *userActivityDictionary =
|
||||
self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey];
|
||||
[self handleInitialLinkFromUniversalLinkURL:userActivityDictionary resolver:resolve rejecter:reject];
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(createDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
@try {
|
||||
FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata];
|
||||
|
||||
if (components == nil) {
|
||||
reject(@"links/failure", @"Failed to create Dynamic Link", nil);
|
||||
} else {
|
||||
NSURL *longLink = components.url;
|
||||
NSLog(@"created long dynamic link: %@", longLink.absoluteString);
|
||||
resolve(longLink.absoluteString);
|
||||
}
|
||||
}
|
||||
@catch(NSException * e) {
|
||||
NSLog(@"create dynamic link failure %@", e);
|
||||
reject(@"links/failure",[e reason], nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(createShortDynamicLink: (NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
@try {
|
||||
FIRDynamicLinkComponents *components = [self getDynamicLinkComponentsFromMetadata:metadata];
|
||||
[self setSuffixParameters:metadata components:components];
|
||||
[components shortenWithCompletion:^(NSURL *_Nullable shortURL,
|
||||
NSArray *_Nullable warnings,
|
||||
NSError *_Nullable error) {
|
||||
if (error) {
|
||||
NSLog(@"create short dynamic link failure %@", [error localizedDescription]);
|
||||
reject(@"links/failure", @"Failed to create Short Dynamic Link", error);
|
||||
}
|
||||
NSURL *shortLink = shortURL;
|
||||
NSLog(@"created short dynamic link: %@", shortLink.absoluteString);
|
||||
resolve(shortLink.absoluteString);
|
||||
}];
|
||||
}
|
||||
@catch(NSException * e) {
|
||||
NSLog(@"create short dynamic link failure %@", e);
|
||||
reject(@"links/failure",[e reason], nil);
|
||||
}
|
||||
}
|
||||
|
||||
- (FIRDynamicLinkComponents *)getDynamicLinkComponentsFromMetadata:(NSDictionary *)metadata {
|
||||
@try {
|
||||
NSURL *link = [NSURL URLWithString:metadata[@"link"]];
|
||||
FIRDynamicLinkComponents *components =
|
||||
[FIRDynamicLinkComponents componentsWithLink:link domain:metadata[@"dynamicLinkDomain"]];
|
||||
|
||||
[self setAndroidParameters:metadata components:components];
|
||||
[self setIosParameters:metadata components:components];
|
||||
[self setSocialMetaTagParameters:metadata components:components];
|
||||
|
||||
return components;
|
||||
}
|
||||
@catch(NSException * e) {
|
||||
NSLog(@"error while building componets from meta data %@", e);
|
||||
@throw;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setAndroidParameters:(NSDictionary *)metadata
|
||||
components:(FIRDynamicLinkComponents *)components {
|
||||
NSDictionary *androidParametersDict = metadata[@"androidInfo"];
|
||||
if (androidParametersDict) {
|
||||
FIRDynamicLinkAndroidParameters *androidParams = [FIRDynamicLinkAndroidParameters
|
||||
parametersWithPackageName: androidParametersDict[@"androidPackageName"]];
|
||||
|
||||
if (androidParametersDict[@"androidFallbackLink"]) {
|
||||
androidParams.fallbackURL = [NSURL URLWithString:androidParametersDict[@"androidFallbackLink"]];
|
||||
}
|
||||
if (androidParametersDict[@"androidMinPackageVersionCode"]) {
|
||||
androidParams.minimumVersion = [androidParametersDict[@"androidMinPackageVersionCode"] integerValue];
|
||||
}
|
||||
components.androidParameters = androidParams;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setIosParameters:(NSDictionary *)metadata
|
||||
components:(FIRDynamicLinkComponents *)components {
|
||||
NSDictionary *iosParametersDict = metadata[@"iosInfo"];
|
||||
if (iosParametersDict) {
|
||||
FIRDynamicLinkIOSParameters *iOSParams = [FIRDynamicLinkIOSParameters
|
||||
parametersWithBundleID:iosParametersDict[@"iosBundleId"]];
|
||||
if (iosParametersDict[@"iosAppStoreId"]) {
|
||||
iOSParams.appStoreID = iosParametersDict[@"iosAppStoreId"];
|
||||
}
|
||||
if (iosParametersDict[@"iosCustomScheme"]) {
|
||||
iOSParams.customScheme = iosParametersDict[@"iosCustomScheme"];
|
||||
}
|
||||
if (iosParametersDict[@"iosFallbackLink"]) {
|
||||
iOSParams.fallbackURL = [NSURL URLWithString:iosParametersDict[@"iosFallbackLink"]];
|
||||
}
|
||||
if (iosParametersDict[@"iosIpadBundleId"]) {
|
||||
iOSParams.iPadBundleID = iosParametersDict[@"iosIpadBundleId"];
|
||||
}
|
||||
if (iosParametersDict[@"iosIpadFallbackLink"]) {
|
||||
iOSParams.iPadFallbackURL = [NSURL URLWithString:iosParametersDict[@"iosIpadFallbackLink"]];
|
||||
}
|
||||
if (iosParametersDict[@"iosMinPackageVersionCode"]) {
|
||||
iOSParams.minimumAppVersion = iosParametersDict[@"iosMinPackageVersionCode"];
|
||||
}
|
||||
components.iOSParameters = iOSParams;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSocialMetaTagParameters:(NSDictionary *)metadata
|
||||
components:(FIRDynamicLinkComponents *)components {
|
||||
NSDictionary *socialParamsDict = metadata[@"socialMetaTagInfo"];
|
||||
if (socialParamsDict) {
|
||||
FIRDynamicLinkSocialMetaTagParameters *socialParams = [FIRDynamicLinkSocialMetaTagParameters parameters];
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSuffixParameters:(NSDictionary *)metadata
|
||||
components:(FIRDynamicLinkComponents *)components {
|
||||
NSDictionary *suffixParametersDict = metadata[@"suffix"];
|
||||
if (suffixParametersDict) {
|
||||
FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options];
|
||||
if ([suffixParametersDict[@"option"] isEqual: @"SHORT"]) {
|
||||
options.pathLength = FIRShortDynamicLinkPathLengthShort;
|
||||
}
|
||||
else if ([suffixParametersDict[@"option"] isEqual: @"UNGUESSABLE"]) {
|
||||
options.pathLength = FIRShortDynamicLinkPathLengthUnguessable;
|
||||
}
|
||||
components.options = options;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation RNFirebaseLinks
|
||||
@end
|
||||
#endif
|
||||
|
||||
|
|
@ -13,6 +13,7 @@ import Storage, { statics as StorageStatics } from './modules/storage';
|
|||
import Database, { statics as DatabaseStatics } from './modules/database';
|
||||
import Messaging, { statics as MessagingStatics } from './modules/messaging';
|
||||
import Firestore, { statics as FirestoreStatics } from './modules/firestore';
|
||||
import Links, { statics as LinksStatics } from './modules/links';
|
||||
import Utils, { statics as UtilsStatics } from './modules/utils';
|
||||
|
||||
const FirebaseCoreModule = NativeModules.RNFirebase;
|
||||
|
@ -35,6 +36,7 @@ export default class FirebaseApp {
|
|||
this.crash = this._staticsOrModuleInstance({}, Crash);
|
||||
this.database = this._staticsOrModuleInstance(DatabaseStatics, Database);
|
||||
this.firestore = this._staticsOrModuleInstance(FirestoreStatics, Firestore);
|
||||
this.links = this._staticsOrModuleInstance(LinksStatics, Links);
|
||||
this.messaging = this._staticsOrModuleInstance(MessagingStatics, Messaging);
|
||||
this.perf = this._staticsOrModuleInstance({}, Performance);
|
||||
this.storage = this._staticsOrModuleInstance(StorageStatics, Storage);
|
||||
|
|
|
@ -14,6 +14,7 @@ import Auth, { statics as AuthStatics } from './modules/auth';
|
|||
import Analytics from './modules/analytics';
|
||||
import Crash from './modules/crash';
|
||||
import Performance from './modules/perf';
|
||||
import Links, { statics as LinksStatics } from './modules/links';
|
||||
import RemoteConfig from './modules/config';
|
||||
import Storage, { statics as StorageStatics } from './modules/storage';
|
||||
import Database, { statics as DatabaseStatics } from './modules/database';
|
||||
|
@ -42,6 +43,7 @@ class FirebaseCore {
|
|||
this.crash = this._appNamespaceOrStatics({}, Crash);
|
||||
this.database = this._appNamespaceOrStatics(DatabaseStatics, Database);
|
||||
this.firestore = this._appNamespaceOrStatics(FirestoreStatics, Firestore);
|
||||
this.links = this._appNamespaceOrStatics(LinksStatics, Links);
|
||||
this.messaging = this._appNamespaceOrStatics(MessagingStatics, Messaging);
|
||||
this.perf = this._appNamespaceOrStatics(DatabaseStatics, Performance);
|
||||
this.storage = this._appNamespaceOrStatics(StorageStatics, Storage);
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
import ModuleBase from './../../utils/ModuleBase';
|
||||
import { areObjectKeysContainedInOther, isObject, isString } from './../../utils';
|
||||
|
||||
const EVENT_TYPE = {
|
||||
Link: 'dynamic_link_received',
|
||||
};
|
||||
|
||||
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
|
||||
*/
|
||||
export default class Links extends ModuleBase {
|
||||
static _NAMESPACE = 'links';
|
||||
static _NATIVE_MODULE = 'RNFirebaseLinks';
|
||||
|
||||
constructor(firebaseApp: Object, options: Object = {}) {
|
||||
super(firebaseApp, options, true);
|
||||
}
|
||||
|
||||
get EVENT_TYPE() {
|
||||
return EVENT_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the link that triggered application open
|
||||
* @returns {Promise.<String>}
|
||||
*/
|
||||
getInitialLink() {
|
||||
return this._native.getInitialLink();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to dynamic links
|
||||
* @param listener
|
||||
* @returns {Function}
|
||||
*/
|
||||
onLink(listener: Function): () => any {
|
||||
const rnListener = this._eventEmitter.addListener(EVENT_TYPE.Link, listener);
|
||||
return () => rnListener.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create long Dynamic Link from parameters
|
||||
* @param parameters
|
||||
* @returns {Promise.<String>}
|
||||
*/
|
||||
createDynamicLink(parameters: Object = {}): Promise<String> {
|
||||
try {
|
||||
checkForMandatoryParameters(parameters);
|
||||
validateParameters(parameters);
|
||||
return this._native.createDynamicLink(parameters);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create short Dynamic Link from parameters
|
||||
* @param parameters
|
||||
* @returns {Promise.<String>}
|
||||
*/
|
||||
createShortDynamicLink(parameters: Object = {}): Promise<String> {
|
||||
try {
|
||||
checkForMandatoryParameters(parameters);
|
||||
validateParameters(parameters);
|
||||
return this._native.createShortDynamicLink(parameters);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const statics = {
|
||||
EVENT_TYPE,
|
||||
};
|
|
@ -70,6 +70,43 @@ export function deepExists(object: Object,
|
|||
return tmp !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deep Check if obj1 keys are contained in obj2
|
||||
* @param obj1
|
||||
* @param obj2
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function areObjectKeysContainedInOther(obj1 : Object, obj2: Object): boolean {
|
||||
if (!isObject(obj1) || !isObject(obj2)) {
|
||||
return false;
|
||||
}
|
||||
const keys1 = Object.keys(obj1);
|
||||
const keys2 = Object.keys(obj2);
|
||||
if (isArrayContainedInOther(keys1, keys2)) {
|
||||
return keys1.filter((key) => {
|
||||
return isObject(obj1[key]);
|
||||
}).reduce((acc, cur) => {
|
||||
return acc && areObjectKeysContainedInOther(obj1[cur], obj2[cur]);
|
||||
}, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if arr1 is contained in arr2
|
||||
* @param arr1
|
||||
* @param arr2
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isArrayContainedInOther(arr1: Array, arr2: Array): boolean {
|
||||
if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
|
||||
return false;
|
||||
}
|
||||
return arr1.reduce((acc, cur) => {
|
||||
return acc && arr2.includes(cur);
|
||||
}, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple is object check.
|
||||
* @param item
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
},
|
||||
"globals": {
|
||||
"__DEV__": true,
|
||||
"window": true
|
||||
"window": true,
|
||||
"fetch": true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ dependencies {
|
|||
compile "com.google.firebase:firebase-perf:$firebaseVersion"
|
||||
compile "com.google.firebase:firebase-storage:$firebaseVersion"
|
||||
compile "com.google.firebase:firebase-firestore:$firebaseVersion"
|
||||
compile "com.google.firebase:firebase-invites:$firebaseVersion"
|
||||
compile "com.android.support:appcompat-v7:26.0.1"
|
||||
compile "com.facebook.react:react-native:+" // From node_modules
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import io.invertase.firebase.config.RNFirebaseRemoteConfigPackage;
|
|||
import io.invertase.firebase.crash.RNFirebaseCrashPackage;
|
||||
import io.invertase.firebase.database.RNFirebaseDatabasePackage;
|
||||
import io.invertase.firebase.firestore.RNFirebaseFirestorePackage;
|
||||
import io.invertase.firebase.links.RNFirebaseLinksPackage;
|
||||
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
|
||||
import io.invertase.firebase.perf.RNFirebasePerformancePackage;
|
||||
import io.invertase.firebase.storage.RNFirebaseStoragePackage;
|
||||
|
@ -44,6 +45,7 @@ public class MainApplication extends Application implements ReactApplication {
|
|||
new RNFirebaseCrashPackage(),
|
||||
new RNFirebaseDatabasePackage(),
|
||||
new RNFirebaseFirestorePackage(),
|
||||
new RNFirebaseLinksPackage(),
|
||||
new RNFirebaseMessagingPackage(),
|
||||
new RNFirebasePerformancePackage(),
|
||||
new RNFirebaseStoragePackage()
|
||||
|
|
|
@ -2047,7 +2047,6 @@
|
|||
"requires": {
|
||||
"anymatch": "1.3.2",
|
||||
"async-each": "1.0.1",
|
||||
"fsevents": "1.1.2",
|
||||
"glob-parent": "2.0.0",
|
||||
"inherits": "2.0.3",
|
||||
"is-binary-path": "1.0.1",
|
||||
|
@ -2525,6 +2524,11 @@
|
|||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||
},
|
||||
"decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
|
||||
},
|
||||
"deep-diff": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.4.tgz",
|
||||
|
@ -3804,791 +3808,6 @@
|
|||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz",
|
||||
"integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"nan": "2.7.0",
|
||||
"node-pre-gyp": "0.6.36"
|
||||
},
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "4.11.8",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"co": "4.6.0",
|
||||
"json-stable-stringify": "1.0.1"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"delegates": "1.0.0",
|
||||
"readable-stream": "2.2.9"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.3",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "0.2.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.6.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.6.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "0.4.2",
|
||||
"bundled": true
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"tweetnacl": "0.14.5"
|
||||
}
|
||||
},
|
||||
"block-stream": {
|
||||
"version": "0.0.9",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"inherits": "2.0.3"
|
||||
}
|
||||
},
|
||||
"boom": {
|
||||
"version": "2.10.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"hoek": "2.16.3"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.7",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"balanced-match": "0.4.2",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"buffer-shims": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.5",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"delayed-stream": "1.0.0"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
},
|
||||
"cryptiles": {
|
||||
"version": "2.0.5",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"boom": "2.10.1"
|
||||
}
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.8",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.4.2",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"jsbn": "0.1.1"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.1.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"asynckit": "0.4.0",
|
||||
"combined-stream": "1.0.5",
|
||||
"mime-types": "2.1.15"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"fstream": {
|
||||
"version": "1.0.11",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"graceful-fs": "4.1.11",
|
||||
"inherits": "2.0.3",
|
||||
"mkdirp": "0.5.1",
|
||||
"rimraf": "2.6.1"
|
||||
}
|
||||
},
|
||||
"fstream-ignore": {
|
||||
"version": "1.0.5",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"fstream": "1.0.11",
|
||||
"inherits": "2.0.3",
|
||||
"minimatch": "3.0.4"
|
||||
}
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"aproba": "1.1.1",
|
||||
"console-control-strings": "1.1.0",
|
||||
"has-unicode": "2.0.1",
|
||||
"object-assign": "4.1.1",
|
||||
"signal-exit": "3.0.2",
|
||||
"string-width": "1.0.2",
|
||||
"strip-ansi": "3.0.1",
|
||||
"wide-align": "1.1.2"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"fs.realpath": "1.0.0",
|
||||
"inflight": "1.0.6",
|
||||
"inherits": "2.0.3",
|
||||
"minimatch": "3.0.4",
|
||||
"once": "1.4.0",
|
||||
"path-is-absolute": "1.0.1"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.1.11",
|
||||
"bundled": true
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "1.0.5",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "4.2.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ajv": "4.11.8",
|
||||
"har-schema": "1.0.5"
|
||||
}
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"hawk": {
|
||||
"version": "3.1.3",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"boom": "2.10.1",
|
||||
"cryptiles": "2.0.5",
|
||||
"hoek": "2.16.3",
|
||||
"sntp": "1.0.9"
|
||||
}
|
||||
},
|
||||
"hoek": {
|
||||
"version": "2.16.3",
|
||||
"bundled": true
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"assert-plus": "0.2.0",
|
||||
"jsprim": "1.4.0",
|
||||
"sshpk": "1.13.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"once": "1.4.0",
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.4",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"number-is-nan": "1.0.1"
|
||||
}
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"jodid25519": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"jsbn": "0.1.1"
|
||||
}
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"json-stable-stringify": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"jsonify": "0.0.0"
|
||||
}
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"jsonify": {
|
||||
"version": "0.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.0.2",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.27.0",
|
||||
"bundled": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.15",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"mime-db": "1.27.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"brace-expansion": "1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"node-pre-gyp": {
|
||||
"version": "0.6.36",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"mkdirp": "0.5.1",
|
||||
"nopt": "4.0.1",
|
||||
"npmlog": "4.1.0",
|
||||
"rc": "1.2.1",
|
||||
"request": "2.81.0",
|
||||
"rimraf": "2.6.1",
|
||||
"semver": "5.3.0",
|
||||
"tar": "2.2.1",
|
||||
"tar-pack": "3.4.0"
|
||||
}
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"abbrev": "1.1.0",
|
||||
"osenv": "0.1.4"
|
||||
}
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"are-we-there-yet": "1.1.4",
|
||||
"console-control-strings": "1.1.0",
|
||||
"gauge": "2.7.4",
|
||||
"set-blocking": "2.0.0"
|
||||
}
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.8.2",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"os-homedir": "1.0.2",
|
||||
"os-tmpdir": "1.0.2"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "0.2.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"bundled": true
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.4.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"deep-extend": "0.4.2",
|
||||
"ini": "1.3.4",
|
||||
"minimist": "1.2.0",
|
||||
"strip-json-comments": "2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.2.9",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"buffer-shims": "1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "1.0.0",
|
||||
"process-nextick-args": "1.0.7",
|
||||
"string_decoder": "1.0.1",
|
||||
"util-deprecate": "1.0.2"
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "2.81.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"aws-sign2": "0.6.0",
|
||||
"aws4": "1.6.0",
|
||||
"caseless": "0.12.0",
|
||||
"combined-stream": "1.0.5",
|
||||
"extend": "3.0.1",
|
||||
"forever-agent": "0.6.1",
|
||||
"form-data": "2.1.4",
|
||||
"har-validator": "4.2.1",
|
||||
"hawk": "3.1.3",
|
||||
"http-signature": "1.1.1",
|
||||
"is-typedarray": "1.0.0",
|
||||
"isstream": "0.1.2",
|
||||
"json-stringify-safe": "5.0.1",
|
||||
"mime-types": "2.1.15",
|
||||
"oauth-sign": "0.8.2",
|
||||
"performance-now": "0.2.0",
|
||||
"qs": "6.4.0",
|
||||
"safe-buffer": "5.0.1",
|
||||
"stringstream": "0.0.5",
|
||||
"tough-cookie": "2.3.2",
|
||||
"tunnel-agent": "0.6.0",
|
||||
"uuid": "3.0.1"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"glob": "7.1.2"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.0.1",
|
||||
"bundled": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.3.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"sntp": {
|
||||
"version": "1.0.9",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"hoek": "2.16.3"
|
||||
}
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.13.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"asn1": "0.2.3",
|
||||
"assert-plus": "1.0.0",
|
||||
"bcrypt-pbkdf": "1.0.1",
|
||||
"dashdash": "1.14.1",
|
||||
"ecc-jsbn": "0.1.1",
|
||||
"getpass": "0.1.7",
|
||||
"jodid25519": "1.0.2",
|
||||
"jsbn": "0.1.1",
|
||||
"tweetnacl": "0.14.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.0.1"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"code-point-at": "1.1.0",
|
||||
"is-fullwidth-code-point": "1.0.0",
|
||||
"strip-ansi": "3.0.1"
|
||||
}
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"ansi-regex": "2.1.1"
|
||||
}
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "2.2.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"block-stream": "0.0.9",
|
||||
"fstream": "1.0.11",
|
||||
"inherits": "2.0.3"
|
||||
}
|
||||
},
|
||||
"tar-pack": {
|
||||
"version": "3.4.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"debug": "2.6.8",
|
||||
"fstream": "1.0.11",
|
||||
"fstream-ignore": "1.0.5",
|
||||
"once": "1.4.0",
|
||||
"readable-stream": "2.2.9",
|
||||
"rimraf": "2.6.1",
|
||||
"tar": "2.2.1",
|
||||
"uid-number": "0.0.6"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.3.2",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"punycode": "1.4.1"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"uid-number": {
|
||||
"version": "0.0.6",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.3.6",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"extsprintf": "1.0.2"
|
||||
}
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"string-width": "1.0.2"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
|
@ -6713,12 +5932,6 @@
|
|||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
|
||||
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz",
|
||||
"integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=",
|
||||
"optional": true
|
||||
},
|
||||
"native-promise-only": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz",
|
||||
|
@ -7235,6 +6448,21 @@
|
|||
"resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz",
|
||||
"integrity": "sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc="
|
||||
},
|
||||
"query-string": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.0.0.tgz",
|
||||
"integrity": "sha1-+99wBLTSr/eS+YcZgbeieU9VWUc=",
|
||||
"requires": {
|
||||
"decode-uri-component": "0.2.0",
|
||||
"object-assign": "4.1.1",
|
||||
"strict-uri-encode": "1.1.0"
|
||||
}
|
||||
},
|
||||
"querystringify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz",
|
||||
"integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs="
|
||||
},
|
||||
"random-bytes": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
|
||||
|
@ -7987,6 +7215,11 @@
|
|||
"resolve-from": "1.0.1"
|
||||
}
|
||||
},
|
||||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz",
|
||||
|
@ -8087,7 +7320,6 @@
|
|||
"anymatch": "1.3.2",
|
||||
"exec-sh": "0.2.1",
|
||||
"fb-watchman": "2.0.0",
|
||||
"fsevents": "1.1.2",
|
||||
"minimatch": "3.0.4",
|
||||
"minimist": "1.2.0",
|
||||
"walker": "1.0.7",
|
||||
|
@ -8497,10 +7729,10 @@
|
|||
"readable-stream": "1.1.14"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
"strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
|
||||
},
|
||||
"string-length": {
|
||||
"version": "1.0.1",
|
||||
|
@ -8535,6 +7767,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
||||
|
@ -8859,6 +8096,15 @@
|
|||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.1.9.tgz",
|
||||
"integrity": "sha1-xn8dd11R8KGJEd17P/rSe7nlvRk=",
|
||||
"requires": {
|
||||
"querystringify": "1.0.0",
|
||||
"requires-port": "1.0.0"
|
||||
}
|
||||
},
|
||||
"user-home": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
"lodash.groupby": "^4.6.0",
|
||||
"lodash.some": "^4.6.0",
|
||||
"prop-types": "^15.6.0",
|
||||
"query-string": "^5.0.0",
|
||||
"react": "^16.0.0",
|
||||
"react-native": "^0.49.1",
|
||||
"react-native-vector-icons": "^4.0.0",
|
||||
|
@ -45,7 +46,8 @@
|
|||
"redux-thunk": "^2.2.0",
|
||||
"should": "^11.2.0",
|
||||
"should-sinon": "^0.0.5",
|
||||
"sinon": "^3.2.1"
|
||||
"sinon": "^3.2.1",
|
||||
"url-parse": "^1.1.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.24.0",
|
||||
|
|
|
@ -10,6 +10,7 @@ import config from './config';
|
|||
import performance from './perf';
|
||||
import admob from './admob';
|
||||
import firestore from './firestore';
|
||||
import links from './links/index';
|
||||
|
||||
window.getCoverage = function getCoverage() {
|
||||
return (JSON.stringify(global.__coverage__));
|
||||
|
@ -27,6 +28,7 @@ const testSuiteInstances = [
|
|||
messaging,
|
||||
performance,
|
||||
storage,
|
||||
links,
|
||||
];
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import firebase from '../../firebase';
|
||||
import TestSuite from '../../../lib/TestSuite';
|
||||
import linksTests from './linksTests';
|
||||
|
||||
const suite = new TestSuite('Links', 'firebase.links()', firebase);
|
||||
|
||||
suite.addTests(linksTests);
|
||||
|
||||
export default suite;
|
|
@ -0,0 +1,439 @@
|
|||
import should from 'should';
|
||||
import URL from 'url-parse';
|
||||
import queryString from 'query-string';
|
||||
|
||||
function linksTests({ describe, it, firebase, tryCatch }) {
|
||||
describe('test links', () => {
|
||||
const links = firebase.native.links();
|
||||
const link = 'https://yoursite.example.com';
|
||||
const dynamicLinkDomain = 'x59dg.app.goo.gl';
|
||||
|
||||
const androidPackageName = 'com.reactnativefirebasedemo';
|
||||
const androidFallbackLink = 'android.fallback.com';
|
||||
const androidMinPackageVersionCode = '42';
|
||||
|
||||
const iosBundleId = 'com.invertase.ReactNativeFirebaseDemo';
|
||||
const iosFallbackLink = 'ios.fallback.com';
|
||||
const iosCustomScheme = 'custom';
|
||||
const iosIpadFallbackLink = 'ios.ipad.fallback.com';
|
||||
const iosIpadBundleId = 'com.invertase.ReactNativeFirebaseDemo';
|
||||
const iosAppStoreId = '0123456789';
|
||||
|
||||
const socialTitle = 'title';
|
||||
const socialDescription = 'description';
|
||||
const socialImageLink = 'test.imageUrl.com';
|
||||
|
||||
it('create long dynamic link with all supported parameters', async () => {
|
||||
const data = {
|
||||
link,
|
||||
dynamicLinkDomain,
|
||||
androidInfo: {
|
||||
androidPackageName,
|
||||
androidFallbackLink,
|
||||
androidMinPackageVersionCode,
|
||||
},
|
||||
iosInfo: {
|
||||
iosBundleId,
|
||||
iosFallbackLink,
|
||||
iosCustomScheme,
|
||||
iosIpadFallbackLink,
|
||||
iosIpadBundleId,
|
||||
iosAppStoreId,
|
||||
},
|
||||
socialMetaTagInfo: {
|
||||
socialTitle,
|
||||
socialDescription,
|
||||
socialImageLink,
|
||||
},
|
||||
};
|
||||
|
||||
const result = await links.createDynamicLink(data);
|
||||
|
||||
const expectedParameters = { sd: socialDescription,
|
||||
si: socialImageLink,
|
||||
st: socialTitle,
|
||||
afl: androidFallbackLink,
|
||||
amv: androidMinPackageVersionCode,
|
||||
apn: androidPackageName,
|
||||
ibi: iosBundleId,
|
||||
ifl: iosFallbackLink,
|
||||
isi: iosAppStoreId,
|
||||
ius: iosCustomScheme,
|
||||
ipbi: iosIpadBundleId,
|
||||
ipfl: iosIpadFallbackLink,
|
||||
link,
|
||||
};
|
||||
|
||||
const url = new URL(result);
|
||||
url.protocol.should.eql('https:');
|
||||
url.hostname.should.eql(dynamicLinkDomain);
|
||||
const params = queryString.parse(url.query);
|
||||
|
||||
Object.keys(expectedParameters).forEach((key) => {
|
||||
const val = expectedParameters[key];
|
||||
params[key].should.eql(val);
|
||||
});
|
||||
});
|
||||
|
||||
it('create long dynamic link with minimal parameters', async () => {
|
||||
const data = {
|
||||
link,
|
||||
dynamicLinkDomain,
|
||||
};
|
||||
|
||||
const result = await links.createDynamicLink(data);
|
||||
|
||||
const url = new URL(result);
|
||||
url.protocol.should.eql('https:');
|
||||
url.hostname.should.eql(dynamicLinkDomain);
|
||||
const params = queryString.parse(url.query);
|
||||
params.link.should.eql(link);
|
||||
});
|
||||
|
||||
it('fail to create long dynamic link with empty data object', () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const success = tryCatch(() => {
|
||||
// Assertion
|
||||
reject(new Error('createDynamicLink did not fail.'));
|
||||
}, reject);
|
||||
|
||||
const failure = tryCatch((error) => {
|
||||
// Assertion
|
||||
error.message.should.equal('No dynamicLinkDomain was specified.');
|
||||
resolve();
|
||||
}, reject);
|
||||
|
||||
const data = { };
|
||||
|
||||
// Test
|
||||
|
||||
links.createDynamicLink(data)
|
||||
.then(success)
|
||||
.catch(failure);
|
||||
});
|
||||
});
|
||||
|
||||
it('fail to create long dynamic link without link object', () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const success = tryCatch(() => {
|
||||
// Assertion
|
||||
reject(new Error('createDynamicLink did not fail.'));
|
||||
}, reject);
|
||||
|
||||
const failure = tryCatch((error) => {
|
||||
// Assertion
|
||||
error.message.should.equal('No link was specified.');
|
||||
resolve();
|
||||
}, reject);
|
||||
|
||||
const data = { dynamicLinkDomain };
|
||||
|
||||
// Test
|
||||
|
||||
links.createDynamicLink(data)
|
||||
.then(success)
|
||||
.catch(failure);
|
||||
});
|
||||
});
|
||||
|
||||
it('fail to create long dynamic link without iosBundleId', () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const success = tryCatch(() => {
|
||||
// Assertion
|
||||
reject(new Error('createDynamicLink did not fail.'));
|
||||
}, reject);
|
||||
|
||||
const failure = tryCatch((error) => {
|
||||
// Assertion
|
||||
error.message.should.equal('No iosBundleId was specified.');
|
||||
resolve();
|
||||
}, reject);
|
||||
|
||||
// Setup
|
||||
const data = {
|
||||
link,
|
||||
dynamicLinkDomain,
|
||||
androidInfo: {
|
||||
androidPackageName,
|
||||
androidFallbackLink,
|
||||
androidMinPackageVersionCode,
|
||||
},
|
||||
iosInfo: {
|
||||
iosFallbackLink,
|
||||
iosCustomScheme,
|
||||
iosIpadFallbackLink,
|
||||
iosIpadBundleId,
|
||||
iosAppStoreId,
|
||||
},
|
||||
socialMetaTagInfo: {
|
||||
socialTitle,
|
||||
socialDescription,
|
||||
socialImageLink,
|
||||
},
|
||||
};
|
||||
|
||||
// Test
|
||||
|
||||
links.createDynamicLink(data)
|
||||
.then(success)
|
||||
.catch(failure);
|
||||
});
|
||||
});
|
||||
|
||||
it('fail to create long dynamic link without androidPackageName', () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const success = tryCatch(() => {
|
||||
// Assertion
|
||||
reject(new Error('createDynamicLink did not fail.'));
|
||||
}, reject);
|
||||
|
||||
const failure = tryCatch((error) => {
|
||||
// Assertion
|
||||
error.message.should.equal('No androidPackageName was specified.');
|
||||
resolve();
|
||||
}, reject);
|
||||
|
||||
// Setup
|
||||
const data = {
|
||||
link,
|
||||
dynamicLinkDomain,
|
||||
androidInfo: {
|
||||
androidFallbackLink,
|
||||
androidMinPackageVersionCode,
|
||||
},
|
||||
iosInfo: {
|
||||
iosBundleId,
|
||||
iosFallbackLink,
|
||||
iosCustomScheme,
|
||||
iosIpadFallbackLink,
|
||||
iosIpadBundleId,
|
||||
iosAppStoreId,
|
||||
},
|
||||
socialMetaTagInfo: {
|
||||
socialTitle,
|
||||
socialDescription,
|
||||
socialImageLink,
|
||||
},
|
||||
};
|
||||
|
||||
// Test
|
||||
|
||||
links.createDynamicLink(data)
|
||||
.then(success)
|
||||
.catch(failure);
|
||||
});
|
||||
});
|
||||
|
||||
it('fail to create long dynamic link with unsupported parameter', () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const success = tryCatch(() => {
|
||||
// Assertion
|
||||
reject(new Error('createDynamicLink did not fail.'));
|
||||
}, reject);
|
||||
|
||||
const failure = tryCatch((error) => {
|
||||
// Assertion
|
||||
error.message.should.equal('Invalid Parameters.');
|
||||
resolve();
|
||||
}, reject);
|
||||
|
||||
const data = {
|
||||
link,
|
||||
dynamicLinkDomain,
|
||||
someInvalidParameter: 'invalid',
|
||||
};
|
||||
|
||||
// Test
|
||||
|
||||
links.createDynamicLink(data)
|
||||
.then(success)
|
||||
.catch(failure);
|
||||
});
|
||||
});
|
||||
|
||||
it('fail to create long dynamic link with unsupported ios parameters', () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const success = tryCatch(() => {
|
||||
// Assertion
|
||||
reject(new Error('createDynamicLink did not fail.'));
|
||||
}, reject);
|
||||
|
||||
const failure = tryCatch((error) => {
|
||||
// Assertion
|
||||
error.message.should.equal('Invalid Parameters.');
|
||||
resolve();
|
||||
}, reject);
|
||||
|
||||
const data = {
|
||||
link,
|
||||
dynamicLinkDomain,
|
||||
androidInfo: {
|
||||
androidPackageName,
|
||||
},
|
||||
iosInfo: {
|
||||
iosBundleId,
|
||||
someInvalidParameter: 'invalid',
|
||||
someOtherParameter: 'invalid',
|
||||
},
|
||||
};
|
||||
|
||||
// Test
|
||||
|
||||
links.createDynamicLink(data)
|
||||
.then(success)
|
||||
.catch(failure);
|
||||
});
|
||||
});
|
||||
|
||||
it('fail to create long dynamic link with unsupported android parameters', () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const success = tryCatch(() => {
|
||||
// Assertion
|
||||
reject(new Error('createDynamicLink did not fail.'));
|
||||
}, reject);
|
||||
|
||||
const failure = tryCatch((error) => {
|
||||
// Assertion
|
||||
error.message.should.equal('Invalid Parameters.');
|
||||
resolve();
|
||||
}, reject);
|
||||
|
||||
const data = {
|
||||
link,
|
||||
dynamicLinkDomain,
|
||||
androidInfo: {
|
||||
androidPackageName,
|
||||
someInvalidParameter: 'invalid',
|
||||
someOtherParameter: 'invalid',
|
||||
},
|
||||
iosInfo: {
|
||||
iosBundleId,
|
||||
},
|
||||
};
|
||||
|
||||
// Test
|
||||
|
||||
links.createDynamicLink(data)
|
||||
.then(success)
|
||||
.catch(failure);
|
||||
});
|
||||
});
|
||||
|
||||
it('fail to create long dynamic link with unsupported social parameters', () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const success = tryCatch(() => {
|
||||
// Assertion
|
||||
reject(new Error('createDynamicLink did not fail.'));
|
||||
}, reject);
|
||||
|
||||
const failure = tryCatch((error) => {
|
||||
// Assertion
|
||||
error.message.should.equal('Invalid Parameters.');
|
||||
resolve();
|
||||
}, reject);
|
||||
|
||||
const data = {
|
||||
link,
|
||||
dynamicLinkDomain,
|
||||
androidInfo: {
|
||||
androidPackageName,
|
||||
},
|
||||
iosInfo: {
|
||||
iosBundleId,
|
||||
},
|
||||
socialMetaTagInfo: {
|
||||
someInvalidParameter: 'invalid',
|
||||
someOtherParameter: 'invalid',
|
||||
},
|
||||
};
|
||||
|
||||
// Test
|
||||
|
||||
links.createDynamicLink(data)
|
||||
.then(success)
|
||||
.catch(failure);
|
||||
});
|
||||
});
|
||||
|
||||
it('create short (unguessable) dynamic link with all supported parameters', async () => {
|
||||
const url = 'https://www.google.co.il/search?q=react+native+firebase';
|
||||
const data = {
|
||||
link: url,
|
||||
dynamicLinkDomain,
|
||||
androidInfo: {
|
||||
androidPackageName,
|
||||
androidFallbackLink,
|
||||
androidMinPackageVersionCode,
|
||||
},
|
||||
iosInfo: {
|
||||
iosBundleId,
|
||||
iosFallbackLink,
|
||||
iosCustomScheme,
|
||||
iosIpadFallbackLink,
|
||||
iosIpadBundleId,
|
||||
iosAppStoreId,
|
||||
},
|
||||
socialMetaTagInfo: {
|
||||
socialTitle,
|
||||
socialDescription,
|
||||
socialImageLink,
|
||||
},
|
||||
};
|
||||
|
||||
const result = await links.createShortDynamicLink(data);
|
||||
result.should.startWith(`https://${dynamicLinkDomain}`);
|
||||
|
||||
const response = await fetch(result);
|
||||
url.should.eql(response.url);
|
||||
});
|
||||
|
||||
it('create short (short) dynamic link with all supported parameters', async () => {
|
||||
const url = 'https://www.google.co.il/search?q=react+native+firebase';
|
||||
const data = {
|
||||
link: url,
|
||||
dynamicLinkDomain,
|
||||
androidInfo: {
|
||||
androidPackageName,
|
||||
androidFallbackLink,
|
||||
androidMinPackageVersionCode,
|
||||
},
|
||||
iosInfo: {
|
||||
iosBundleId,
|
||||
iosFallbackLink,
|
||||
iosCustomScheme,
|
||||
iosIpadFallbackLink,
|
||||
iosIpadBundleId,
|
||||
iosAppStoreId,
|
||||
},
|
||||
socialMetaTagInfo: {
|
||||
socialTitle,
|
||||
socialDescription,
|
||||
socialImageLink,
|
||||
},
|
||||
suffix: {
|
||||
option: 'SHORT',
|
||||
},
|
||||
};
|
||||
|
||||
const result = await links.createShortDynamicLink(data);
|
||||
result.should.startWith(`https://${dynamicLinkDomain}`);
|
||||
|
||||
const response = await fetch(result);
|
||||
url.should.eql(response.url);
|
||||
});
|
||||
|
||||
it('getInitialLink should return null', async () => {
|
||||
const initialLink = await links.getInitialLink();
|
||||
should(initialLink).be.null();
|
||||
});
|
||||
|
||||
it('should listen to link', () => {
|
||||
const unsubscribe = links.onLink((url: string) => {
|
||||
console.log(url);
|
||||
// handle link
|
||||
});
|
||||
unsubscribe();
|
||||
});
|
||||
});
|
||||
}
|
||||
export default linksTests;
|
Loading…
Reference in New Issue