invertase / react-native-firebase

🔥 A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.63k stars 2.2k forks source link

[🐛] 🔥 dynamicLinks().newDynamicLinkParameters() throws an error #4927

Closed cmbritten closed 3 years ago

cmbritten commented 3 years ago

Issue

Describe your issue here

Hello, I am trying to build a dynamic link for an iOS app. I am attempting to use the library to build the link within the app. I have been able to build/open dynamic links so long as the links are created in the firebase console, but building the links in the app is throwing an error if I try to set any iosParameters.

I am following the code examples here:

  1. https://rnfirebase.io/dynamic-links/usage#create-a-link
  2. https://rnfirebase.io/reference/dynamic-links/dynamiclinkiosparameters

When a user presses a button to build a shareable dynamic link, I call this function:

import dynamicLinks from '@react-native-firebase/dynamic-links';

/// ...

async function sharedLinkBuilder(recallID, subtitle, title) {

// PART 1

const linkParams = dynamicLinks().newDynamicLinkParameters('https://###', 'https://###')

linkParams
 .ios.setBundleId('###')
.ios.setAppStoreId('###')

// PART 2

  const link = await dynamicLinks().buildShortLink({
    link: 'https://#####',

  domainUriPrefix: 'https://###',
  social: {
    title: title,
    descriptionText: `${subtitle}.###.`,
    imageUrl: '###'
  },

// Include iOS parameters
  ios: {
    appStoreID: '###',
    bundleId: '###,

  }

  }, );

I then receive an error, the full text of which is below:

TypeError: (0, _dynamicLinks.default)().newDynamicLinkParameters is not a function. (In '(0, _dynamicLinks.default)().newDynamicLinkParameters('{my link here}', '{my prefix link here}')', '(0, _dynamicLinks.default)().newDynamicLinkParameters' is undefined)

Note that if I do include the code in part 1, and also do not set the code in "//include iOS parameters", everything works great (but the link does not then have full features, since it doesn't know it's ios parameters -- that is, it does not open in the app store when users dont have the iOS app installed, it goes to the web url)

Full error

[Thu Feb 18 2021 11:05:02.493]  WARN     Possible Unhandled Promise Rejection (id: 6):
TypeError: (0, _dynamicLinks.default)().newDynamicLinkParameters is not a function. (In '(0, _dynamicLinks.default)().newDynamicLinkParameters('{my link here}', '{my prefix link here}')', '(0, _dynamicLinks.default)().newDynamicLinkParameters' is undefined)
sharedLinkBuilder$@http://localhost:8081/utils/shareAnArticle.bundle?platform=ios&dev=true&minify=false&modulesOnly=true&runModule=false&shallow=true:29:79
tryCatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29455:23
invoke@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29628:32
tryCatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29455:23
invoke@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29528:30
http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29558:19
tryCallTwo@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:4358:9
doResolve@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:4522:25
Promise@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:4381:14
callInvokeWithMethodAndArg@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29557:33
enqueue@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29562:157
http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29579:69
sharedLinkBuilder@http://localhost:8081/utils/shareAnArticle.bundle?platform=ios&dev=true&minify=false&modulesOnly=true&runModule=false&shallow=true:25:38
shareAnArticle$@http://localhost:8081/utils/shareAnArticle.bundle?platform=ios&dev=true&minify=false&modulesOnly=true&runModule=false&shallow=true:65:64
tryCatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29455:23
invoke@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29628:32
tryCatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29455:23
invoke@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29528:30
http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29558:19
tryCallTwo@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:4358:9
doResolve@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:4522:25
Promise@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:4381:14
callInvokeWithMethodAndArg@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29557:33
enqueue@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29562:157
http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29579:69
shareAnArticle@http://localhost:8081/utils/shareAnArticle.bundle?platform=ios&dev=true&minify=false&modulesOnly=true&runModule=false&shallow=true:60:38
onShare$@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:343253:41
tryCatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29455:23
invoke@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29628:32
tryCatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29455:23
invoke@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29528:30
http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29558:19
tryCallTwo@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:4358:9
doResolve@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:4522:25
Promise@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:4381:14
callInvokeWithMethodAndArg@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29557:33
enqueue@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29562:157
http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:29579:69
onShare@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:343249:38
onPress@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:343925:23
onPress@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:70444:35
_performTransitionSideEffects@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:56431:22
_receiveSignal@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:56373:45
onResponderRelease@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:56282:34
invokeGuardedCallbackImpl@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:13665:21
invokeGuardedCallback@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:13759:42
invokeGuardedCallbackAndCatchFirstError@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:13763:36
executeDispatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:13835:48
executeDispatchesInOrder@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:13855:26
executeDispatchesAndRelease@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:14930:35
forEach@[native code]
forEachAccumulated@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:13997:22
runEventsInBatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:14954:27
runExtractedPluginEventsInBatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:15033:25
http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:15009:42
batchedUpdates$1@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:25658:20
batchedUpdates@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:14916:36
_receiveRootNodeIDEvent@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:15008:23
receiveTouches@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:15061:34
__callFunction@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:3672:36
http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:3404:31
__guard@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:3626:15
callFunctionReturnFlushedQueue@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:3403:21
callFunctionReturnFlushedQueue@[native code]

Project Files

Javascript

Click To Expand

#### `package.json`: ```json { "main": "index.js", "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "web": "expo start --web", "start": "react-native start", "test": "jest" }, "dependencies": { "@react-native-community/datetimepicker": "^3.0.9", "@react-native-community/masked-view": "^0.1.10", "@react-native-firebase/analytics": "^10.6.4", "@react-native-firebase/app": "^10.6.4", "@react-native-firebase/auth": "^10.6.4", "@react-native-firebase/dynamic-links": "^10.7.0", "@react-navigation/bottom-tabs": "^5.11.7", "@react-navigation/drawer": "^5.12.3", "@react-navigation/native": "^5.9.2", "@react-navigation/stack": "^5.14.2", "algoliasearch": "^4.8.5", "date-fns": "^2.17.0", "expo": "~40.0.0", "expo-apple-authentication": "^3.0.0", "expo-constants": "^10.0.1", "expo-crypto": "^9.0.0", "expo-font": "^9.0.0", "expo-google-sign-in": "^9.0.0", "expo-notifications": "^0.9.0", "expo-splash-screen": "~0.8.0", "expo-status-bar": "~1.0.3", "expo-updates": "~0.4.0", "firebase": "^8.2.6", "lottie-react-native": "^3.5.0", "react": "16.13.1", "react-dom": "16.13.1", "react-instantsearch-dom": "^6.9.0", "react-instantsearch-native": "^6.9.0", "react-native": "~0.63.4", "react-native-app-intro-slider": "^4.0.4", "react-native-appsflyer": "^6.1.41", "react-native-card-flip": "^1.0.7", "react-native-elements": "^3.2.0", "react-native-fast-image": "^8.3.4", "react-native-fbsdk": "^3.0.0", "react-native-gesture-handler": "~1.8.0", "react-native-hyperlink": "^0.0.19", "react-native-image-modal": "^2.0.2", "react-native-inset-shadow": "^1.0.3", "react-native-mixpanel": "^1.2.5", "react-native-modal": "^11.6.1", "react-native-paper": "^4.7.1", "react-native-progress": "^4.1.2", "react-native-purchases": "^4.0.0", "react-native-rate": "^1.2.4", "react-native-raw-bottom-sheet": "^2.2.0", "react-native-reanimated": "~1.13.0", "react-native-safe-area-context": "^3.1.9", "react-native-screens": "~2.15.0", "react-native-snap-carousel": "^3.9.1", "react-native-status-bar-height": "^2.6.0", "react-native-svg": "^12.1.0", "react-native-swiper": "^1.6.0", "react-native-tab-view": "^2.15.2", "react-native-unimodules": "~0.12.0", "react-native-vector-icons": "^8.0.0", "react-native-web": "~0.13.12", "react-string-replace": "^0.4.4" }, "devDependencies": { "@babel/core": "~7.9.0", "babel-jest": "~25.2.6", "jest": "~25.2.6", "react-native-svg-transformer": "^0.14.3", "react-test-renderer": "~16.13.1" }, "jest": { "preset": "react-native" }, "private": true } ``` #### `firebase.json` for react-native-firebase v6: ```json import firebase from "@firebase/app" // import * as firebase from 'firebase' -- https://forums.expo.io/t/issues-between-react-native-app-and-firebase/11539/3 // Initialize Firebase const firebaseConfig = { [config block] }; firebase.initializeApp(firebaseConfig); export default firebase; ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/react-native-unimodules/cocoapods.rb' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' platform :ios, '11.0' target '{myTarget}' do use_unimodules! config = use_native_modules! use_react_native!(:path => config["reactNativePath"]) # Uncomment the code below to enable Flipper. # # You should not install Flipper in CI environments when creating release # builds, this will lead to significantly slower build times. # # Note that if you have use_frameworks! enabled, Flipper will not work. # # use_flipper! # post_install do |installer| # flipper_post_install(installer) # end end ``` #### `AppDelegate.m`: ```objc #import "AppDelegate.h" #import #import #import #import #import #import #import #import #import #import #import #import #if defined(FB_SONARKIT_ENABLED) && __has_include() #import #import #import #import #import #import static void InitializeFlipper(UIApplication *application) { FlipperClient *client = [FlipperClient sharedClient]; SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; [client addPlugin:[FlipperKitReactPlugin new]]; [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; [client start]; } #endif @interface AppDelegate () @property (nonatomic, strong) UMModuleRegistryAdapter *moduleRegistryAdapter; @property (nonatomic, strong) NSDictionary *launchOptions; @end @implementation AppDelegate - (void)applicationDidBecomeActive:(UIApplication *)application { [FBSDKAppEvents activateApp]; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { #if defined(FB_SONARKIT_ENABLED) && __has_include() InitializeFlipper(application); #endif self.moduleRegistryAdapter = [[UMModuleRegistryAdapter alloc] initWithModuleRegistryProvider:[[UMModuleRegistryProvider alloc] init]]; self.launchOptions = launchOptions; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; #ifdef DEBUG [self initializeReactNativeApp]; #else EXUpdatesAppController *controller = [EXUpdatesAppController sharedInstance]; controller.delegate = self; [controller startAndShowLaunchScreen:self.window]; #endif [super application:application didFinishLaunchingWithOptions:launchOptions]; [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions]; if ([FIRApp defaultApp] == nil) { [FIRApp configure]; } return YES; } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; } - (RCTBridge *)initializeReactNativeApp { RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:self.launchOptions]; RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil]; rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; return bridge; } - (NSArray> *)extraModulesForBridge:(RCTBridge *)bridge { NSArray> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge]; // If you'd like to export some custom RCTBridgeModules that are not Expo modules, add them here! return extraModules; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #ifdef DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; #else return [[EXUpdatesAppController sharedInstance] launchAssetUrl]; #endif } - (void)appController:(EXUpdatesAppController *)appController didStartWithSuccess:(BOOL)success { appController.bridge = [self initializeReactNativeApp]; EXSplashScreenService *splashScreenService = (EXSplashScreenService *)[UMModuleRegistryProvider getSingletonModuleForClass:[EXSplashScreenService class]]; [splashScreenService showSplashScreenFor:self.window.rootViewController]; } - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { RNFBDynamicLinksAppDelegateInterceptor *interceptor = [RNFBDynamicLinksAppDelegateInterceptor sharedInstance]; if (url && !interceptor.initialLinkUrl) { FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; if (dynamicLink.url) { interceptor.initialLinkUrl = dynamicLink.url.absoluteString; interceptor.initialLinkMinimumAppVersion = dynamicLink.minimumAppVersion == nil ? [NSNull null] : dynamicLink.minimumAppVersion; } } return YES; } - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> * _Nullable))restorationHandler { id completion = ^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) { if (!error && dynamicLink && dynamicLink.url) { RNFBDynamicLinksAppDelegateInterceptor *interceptor = [RNFBDynamicLinksAppDelegateInterceptor sharedInstance]; interceptor.initialLinkUrl = dynamicLink.url.absoluteString; interceptor.initialLinkMinimumAppVersion = dynamicLink.minimumAppVersion; } }; [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL completion:completion]; return YES; } @end ```


Android

Click To Expand

#### Have you converted to AndroidX? - [ ] my application is an AndroidX application? - [ ] I am using `android/gradle.settings` `jetifier=true` for Android compatibility? - [ ] I am using the NPM package `jetifier` for react-native compatibility? #### `android/build.gradle`: ```groovy // N/A ``` #### `android/app/build.gradle`: ```groovy // N/A ``` #### `android/settings.gradle`: ```groovy // N/A ``` #### `MainApplication.java`: ```java // N/A ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` info Fetching system and libraries information... (node:77302) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency (Use `node --trace-warnings ...` to show where the warning was created) System: OS: macOS 11.0.1 CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz Memory: 436.96 MB / 8.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 14.15.0 - /usr/local/bin/node Yarn: 1.22.4 - ~/.yarn/bin/yarn npm: 6.14.7 - ~/.npm-global/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman Managers: CocoaPods: 1.10.1 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2 Android SDK: Not Found IDEs: Android Studio: 4.0 AI-193.6911.18.40.6514223 Xcode: 12.4/12D4e - /usr/bin/xcodebuild Languages: Java: 14.0.1 - /usr/bin/javac Python: 2.7.16 - /usr/bin/python npmPackages: @react-native-community/cli: Not Found react: 16.13.1 => 16.13.1 react-native: ~0.63.4 => 0.63.4 react-native-macos: Not Found npmGlobalPackages: *react-native*: Not Found ``` - **Platform that you're experiencing the issue on**: - [ ] iOS - [ ] Android - [X] **iOS** but have not tested behavior on Android - [ ] **Android** but have not tested behavior on iOS - [ ] Both - **`react-native-firebase` version you're using that has this issue:** - `10.6.4` - **`Firebase` module(s) you're using that has the issue:** - `DynamicLinks` - **Are you using `TypeScript`?** - `N`


mikehardy commented 3 years ago

This seems to work for me?

  firebase
        .dynamicLinks()
        .buildShortLink(
          {
            link: `${AppConfig.getWebAppURIRoot()}/${user.profileName}`,
            domainUriPrefix: AppConfig.getDeepLinkRoot(),
            android: {
              packageName: AppConfig.getAndroidPackage(),
            },
            ios: {
              bundleId: AppConfig.getIOSBundle(),
              appStoreId: AppConfig.getIOSAppId(),
            },
            social: {
              title: `${user.profileName} ${I18NService.translate(
                'ProfileShareSocialYour'
              )} Komp.ai`,
              descriptionText: I18NService.translate('ProfileShareSocialDescription'),
              imageUrl: `${AppConfig.getWebAppURIRoot()}/ms-icon-310x310.png`,
            },
          },
          firebase.dynamicLinks.ShortLinkType.SHORT
        )
        .then((link) => {
          console.log(`DynamicLinkStore::getProfileLink - got link: ${link}`);
          DynamicLinkStore.currentUserProfileLink = link;
          this.trigger();
        })
        .catch((err) => {
          console.log('DynamicLinkStore::getProfileLink - unable to build link?', err);
          DynamicLinkStore.profileLinkLoading = false;
        });
cmbritten commented 3 years ago

Thanks very much mike! I used your code example and got mine working.

mikehardy commented 3 years ago

I love it when things work, glad that worked for you. Good luck with your project!

luckydunia054 commented 1 year ago

Hi @mikehardy i am using firebase.dynamicLinks.ShortLinkType.SHORT but not able to create it for particular length of 10 characters. where i have to pass the character length.

mikehardy commented 1 year ago

@luckydunia054 that is called "thread-jacking" -

(Internet) The act of taking over an e-mail list or discussion thread with a subject unrelated to the original posting.

My guess is something related to this https://rnfirebase.io/reference/dynamic-links/shortlinktype but you may also just reference the firebase-js-sdk APIs or ask on stackoverflow as I do not believe this is a react-native-firebase specific question