React-native-firebase: ๐Ÿ”ฅ Dynamic link first open attribution not working on IOS

Created on 14 Feb 2019  ยท  15Comments  ยท  Source: invertase/react-native-firebase

Issue

First of all i am not facing issues when i click over a link, my app is opened properly.

I am trying to attribute a campaign, source and medium to a dynamic link install on IOS.

I first open the dynamic link and click over the "open" button on the preview.page.link of the dynamic link. The link is copied to the clipboard.

Then I install the app via XCode and i checked that the dynamic link is fired on the javascript side. The ios function that was fired was application:openURL:options and as i debugged it this was the url:

com.example.app://google/link/?deep_link_id=https%3A%2F%2Fhola%2Ecom%2Ftest&match_type=unique&match_message=Link%20is%20uniquely%20matched%20for%20this%20device%2E

image

If i click on a dynamic link, and my app is already installed the attribution works properly. The IOS function fired is application:continueUserActivity:restorationHandler

image

If I check on firebase the event has lots of (direct), which means the attribution failed:

image


Project Files

iOS

ios/Podfile:

  • [ ] I'm not using Pods
  • [x] I'm using Pods and my Podfile looks like:
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'ExampleAPp' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!

  # Pods for ExampleApp
  pod 'Firebase/Core', '~> 5.15.0'
  pod 'Firebase/Auth', '~> 5.15.0'
  pod 'Firebase/Messaging', '~> 5.15.0'
  pod 'Fabric', '~> 1.7.13'
  pod 'Crashlytics', '~> 3.10.7'
  pod 'Firebase/Database', '~> 5.15.0'
  pod 'Firebase/DynamicLinks', '~> 5.15.0'

  pod 'GoogleSignIn', '~> 4.2.0'
  pod 'FBSDKCoreKit', '~> 4.35.0', :modular_headers => true
  pod 'FBSDKLoginKit', '~> 4.35.0', :modular_headers => true
  pod 'FBSDKShareKit', '~> 4.35.0', :modular_headers => true
  pod 'AppsFlyerFramework'

  pod 'TwilioVideo', '~> 2.5.6'

  target 'ExampleAppTest' do
    inherit! :search_paths
    # Pods for testing
  end

end

target 'ExampleApp-tvOS' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!

  # Pods for ExampleApp-tvOS

  target 'ExampleApp-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

# The following is needed to ensure the "archive" step works in XCode.
# It removes React from the Pods project, as it is already included in the main project.
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == "React"
      target.remove_from_project
    end
  end
end

AppDelegate.m:

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#import <Firebase.h>
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "RNFirebaseLinks.h"
#import "RNFirebaseMessaging.h"
#import "RNFirebaseNotifications.h"
#import <React/RCTLinkingManager.h>
#import <RNGoogleSignin/RNGoogleSignin.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <AppsFlyerLib/AppsFlyerTracker.h>
#import <Fabric/Fabric.h>
#import <Crashlytics/Crashlytics.h>
#import "RNSplashScreen.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  [FIROptions defaultOptions].deepLinkURLScheme = @"com.example.app";
  [FIRApp configure];
  [RNFirebaseNotifications configure];
  [FIRDatabase database].persistenceEnabled = YES;
  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"ExampleApp"
                                               initialProperties:nil
                                                   launchOptions:launchOptions];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  [RNSplashScreen show];
  [Fabric with:@[[Crashlytics class]]];
  return YES;
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
  BOOL handled = [RCTLinkingManager
                  application:application
                  openURL:url
                  sourceApplication:sourceApplication
                  annotation:annotation
                  ];
  return handled;
}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
  NSLog(@"Hola1: %@", url);
  BOOL handled = [[RNFirebaseLinks instance]
                  application:application
                  openURL:url
                  options:options
                  ] || [RCTLinkingManager
                        application:application
                        openURL:url
                        options:options
                        ] || [[FBSDKApplicationDelegate sharedInstance]
                              application:application
                              openURL:url
                              sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
                              annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
                              ] || [RNGoogleSignin
                                    application:application
                                    openURL:url
                                    sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
                                    annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
                                    ];

  return handled;
}

- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
 restorationHandler:(void (^)(NSArray *))restorationHandler {
  BOOL handled = [[RNFirebaseLinks instance]
                  application:application
                  continueUserActivity:userActivity
                  restorationHandler:restorationHandler
                  ] || [RCTLinkingManager
                        application:application
                        continueUserActivity:userActivity
                        restorationHandler:restorationHandler
                        ];

  return handled;
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
  [[RNFirebaseNotifications instance] didReceiveLocalNotification:notification];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
                                                       fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
  [[RNFirebaseNotifications instance] didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
  [[RNFirebaseMessaging instance] didRegisterUserNotificationSettings:notificationSettings];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
  [FBSDKAppEvents activateApp];
}

@end

Android

android/build.gradle:

// N/A

android/app/build.gradle:

// N/A

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

<!-- N/A -->

Environment

  • Platform that you're experiencing the issue on:

    • [x] iOS

    • [ ] Android

    • [ ] iOS but have not tested behavior on Android

    • [ ] Android but have not tested behavior on iOS

    • [ ] Both

  • If known, the version of the platform are you experiencing the issue on:

    • ADD_SOMETHING_HERE e.g. iOS 10 or Android API 28

  • Operating System:

    • [x] MacOS, version: N/A

    • [ ] Windows, version: N/A

    • [ ] Other, please specify: N/A

  • Build Tools:

    • Xcode 10

  • React Native version:

    • 0.57.8

  • React Native Firebase library version:

    • 5.2.0

  • Firebase module(s) you're using that has the issue:

    • [ ] N/A

    • [ ] Authentication

    • [x] Analytics

    • [ ] Cloud Firestore

    • [ ] Cloud Messaging (FCM)

    • [ ] Crashlytics

    • [x] Dynamic Links

    • [ ] Functions Callable

    • [ ] In App Messaging

    • [ ] Indexing

    • [ ] Invites

    • [ ] Instance ID

    • [ ] ML Kit

    • [ ] Notifications

    • [ ] Performance Monitoring

    • [ ] Realtime Database

    • [ ] Remote Config

    • [ ] Storage

  • Are you using TypeScript?

    • [x] No

    • [ ] Yes, version: N/A

  • Are you using Expo, e.g. ExpoKit?

    • [x] No

    • [ ] Yes, I've _not_ ejected

    • [ ] Yes, but I have ejected to ExpoKit

    • [ ] Yes, but I have ejected to vanilla React Native

    • Expo version: N/A




Think react-native-firebase is great? Please consider supporting the project with any of the below:

Stale

Most helpful comment

Thats not the problem i am facing.
My dynamic link works fine, but the attribution on firebase analytics is the thing that is not working properly.
When ever a IOS user executes a dynamic link, the attribution is tracked as (direct), although the link has utm_source, utm_campaign and utm_medium

All 15 comments

same here, First times install app, it redirect to safari with a message Dynamic Link not found

Thats not the problem i am facing.
My dynamic link works fine, but the attribution on firebase analytics is the thing that is not working properly.
When ever a IOS user executes a dynamic link, the attribution is tracked as (direct), although the link has utm_source, utm_campaign and utm_medium

I have a very similar problem. I've followed the instructions to setup dynamic links and try to get the attribution working. dynamic_link_app_open event contains campaign info but dynamic_link_first_open does not :( I see the same results on the production version of the app as well as in debug mode while testing. It's working properly on Android. The links are redirecting as expected. I guess there must be something special about handling the initial link that makes it not passing the campaign data.

Is there actually anyone here that has set this up successfully? It would be great to know if there's something wrong/specific with our code or maybe it just doesn't work for some reason. I've also got a confirmation from Firebase team that (at least in vanilla Firebase libs) attribution on iOS should be working too, even on an unpublished app.

It would be great if anyone from Invertase team shared their thoughts on this problem. CC: @Salakar @Ehesp @chrisbianca

Thanks for the help in advance.

Damian

I debugged it and found that apparently there's an issue in native iOS Firebase library. I've filed an issue to Firebase team and they just started working on it. Fingers crossed!

https://github.com/firebase/firebase-ios-sdk/issues/2462

@damienix Thank you for the relpy and the creation of the issue on the firebase ios sdk.
I will follow that issue, but could you pleae keep this ticket up to date so everybody knows when it is fixed? Thanks!

I'll try my best not to forget about that :)

The fix https://github.com/firebase/firebase-ios-sdk/pull/2478 has been merged to master, we're waiting for the release to test: โœŠ

Maybe while we wait for the 5.19.0 we can use this:

image

Hello ๐Ÿ‘‹, this issue has been automatically marked as stale because it has not had activity for quite some time. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. Thank you for your contributions.

I didn't manage to validate the correctness of the fix provided by Google. It seems to me that it still doesn't work but that would require further investigation from me which I gave up on.

It's almost certain though the issue is with Google native library and not RNF, hence this issue may be closed.

Hello ๐Ÿ‘‹, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time. Has this issue been fixed, or does it still require the community's attention?

This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.

still getting direct open only in iOS. Does anyone has a fix on that?

Yes it redirect to request_ip_version=IP%5FV4&match_message=No%20pre%2Dinstall%20link%20matched%20for%20this%20device%2E"

we are having issues with this exact issue. Please fix it.

This is a problem originally opened May 2019, if this is still ocurring I would open a fresh issue with full details, and an App.js reproduction based on current stable versions (including an override to iOS pod 6.33.0 to make sure you have all fixes - there were recent ones in dynamic links)

I would strongly advise checking the firebase-ios-sdk repository as well, I believe this is back-end functionality on firebase servers so I'm not sure there will be any action here in the end, meaning final resolution will likely be that it is a known issue in their repo that cannot be solved for technical reasons, or that you'll need a clean reproduction without react-native based on their quickstart: https://github.com/firebase/quickstart-ios/tree/master/dynamiclinks

None of that is fun or easy but this is a complicated area of the API surface and that's the work required to troubleshoot and isolate issues - clean reproductions possibly isolating layers of the system to find the source

Was this page helpful?
0 / 5 - 0 ratings