firebase-ios-sdk icon indicating copy to clipboard operation
firebase-ios-sdk copied to clipboard

Deferred dynamic link doesn't work with FirebaseDeepLinkPasteboardRetrievalEnabled set to FALSE

Open jc-paris opened this issue 3 years ago • 28 comments
trafficstars

[REQUIRED] Step 1: Describe your environment

  • Xcode version: Version 13.4.1 (13F100)
  • Firebase SDK version: 9.0.0
  • Installation method: Zip file
  • Firebase Component: DynamicLinks
  • Target platform(s): iOS

[REQUIRED] Step 2: Describe the problem

Steps to reproduce:

  1. Open a dynamic link on safari
  2. As you don't have the app installed yet you see the preview page
  3. Click on the "open" button which direct you to the store
  4. Install the Xcode build which disable PasteboardRetriaval with FirebaseDeepLinkPasteboardRetrievalEnabled: 0 in Info.plist

Notice that you don't have pasteboard notice. Notice the request to https://firebasedynamiclinks.googleapi.com/v1 using a proxy tool.

  1. In the body of the request, we can see that no uniqueMatchLinkToCheck is provided (nothing retrieved from the pasteboard)
  2. Here is the response:
{
	"matchMessage": "No pre-install link matched for this device.",
	"requestIpVersion": "IP_V4"
}

Relevant Code:

The code is working perfectly well in case I keep the FirebaseDeepLinkPasteboardRetrievalEnabled set to true (access to pasteboard, linked matched an provided to the app).

While browsing Firebase Dynamic Link code, I notice this comment in the code: https://github.com/firebase/firebase-ios-sdk/blob/97aff9edf50601bd9ab39ea29c8b1e6e020efe80/FirebaseDynamicLinks/Sources/FIRDLDefaultRetrievalProcessV2.m#L142

Which would suggest that another request should be made using fingerprinting when there is no uniq match (which I believe is the case here). Does fingerprinting method still work on iOS 15 (was it relying on the IDFA which is not available at first app launch since iOS 14 ?)

Also, I'm trying to find the list of attributes Firebase uses for fingerprinting (request from my DPO to make sure we can rely on this matching method).

jc-paris avatar Jul 26 '22 09:07 jc-paris

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

google-oss-bot avatar Jul 26 '22 09:07 google-oss-bot

Thanks for reaching out, @jc-paris. Does the issue occur every time you open the link? Also, could you confirm if your preview page is enabled?

rizafran avatar Jul 27 '22 18:07 rizafran

Hi @rizafran

I confirm this issue occurs every time I open the link (and install the app, if the app is already installed not trouble of course). I've never successfully got it working with more than 10 tests on different devices.

The preview page is enabled, I've tried by checking and not checking the copies to clipboard box, nothing changes. Not that I expected any different behaviour as the clipboard won't be used in our case, but just wanted to make sure.

Thanks for having a look at this issue !

jc-paris avatar Jul 27 '22 18:07 jc-paris

Hi @jc-paris, I tried to reproduce the issue using the FDL Quickstart, but my FDL worked as I'm getting a weak match result which is intended based on this comment. To make sure that we're on the same page, could you provide the following details:

  • Your expected behavior
  • Confirmation if you're using the simulator or real device
  • Confirmation if you have received error logs from self-diagnostic tool

rizafran avatar Aug 02 '22 16:08 rizafran

Hello @rizafran, thanks for your investigation !

  • My expected behavior is to receive the link with a weak match. Currently, as shown by the request response I get no match.
  • I'm using a real device, with an ad-hoc build. My test consist of clicking the dynamic link, opening App Store. Then install my custom build with the FirebaseDeepLinkPasteboardRetrievalEnabled flag disabled.
  • The self-diagnostic show error about the AppDelegate not implementing application:openURL:options: (which is normal as we now use SceneDelegate.scene(_:openURLContexts:) method).
---- Firebase Dynamic Links diagnostic output start ----
Firebase Dynamic Links framework version 9.0.0
System information: OS iOS, OS version 15.6, model iPhone
Current date 2022-08-02 17:02:01 +0000
Device locale en-FR (raw en_FR), timezone Europe/Paris
ERROR: UIApplication delegate <AppDelegate: 0x283b04200> does not implements selector application:openURL:options:. FDL depends on this implementation to retrieve pending dynamic link.
	Specified custom URL scheme is <obfuscated> and Info.plist contains such scheme in CFBundleURLTypes key.
	AppID Prefix: <obfuscated>, Team ID: <obfuscated>, AppId Prefix equal to Team ID: NO
performDiagnostic detected 1 ERRORS.
---- Firebase Dynamic Links diagnostic output end ----

I was wondering if things like ATT (no IDFA) or any other device / privacy setting may impact the fingerprinting happening without the pasteboard (maybe things like iCloud Private Relay, but it's off on my device ?). Could it also be anything in our project Firebase setup which would limit Firebase ability to use fingerprinting for our app?

jc-paris avatar Aug 02 '22 17:08 jc-paris

Hi @rizafran,

I've just tested with the QuickStart Xcode project but using my app project. I get the same behavior. The HTTP response for firebase server is still

{
	"matchMessage": "No pre-install link matched for this device.",
	"requestIpVersion": "IP_V4"
}

But what is weird is that I get this UI (saying strong match but no URL) 🤔

jc-paris avatar Aug 02 '22 17:08 jc-paris

Thanks for that detailed explanation, @jc-paris. AFAIK, FDL is not affected if IDFA is not accessible. As stated on the doc:

No impact for link-opening functionality. When used with Google Analytics, attribution for link conversion events is unavailable.

Regarding the result of your test, it's weird since I was able to get the URL and the weak match result. It seems like there's something missing in your configuration? But I'll try to reproduce again using the same SDK version and installation method you mentioned to see if I'll get the same behavior.

rizafran avatar Aug 02 '22 18:08 rizafran

Hi @jc-paris, I've tried using version 9.0 and installed it via zip file, but I'm still able to get the correct result and its URL. It's possible that there's something missing in your configuration. For us to better figure out what's going on here, could you provide an MCVE that reproduces the issue? Thanks.

rizafran avatar Aug 03 '22 16:08 rizafran

What is a MCVE ?

jc-paris avatar Aug 03 '22 17:08 jc-paris

Sorry for the confusion. It means minimal, reproducible app.

rizafran avatar Aug 03 '22 17:08 rizafran

Here you go: dynamiclinks.zip

With the test link: https://testdfdl.page.link/ib87

(note that I used fake value for AppStore ID and Team ID to not share sensitive information about my app. I could in private message if needed. But I'm able to reproduce also with this MCVE, so it should be good).

jc-paris avatar Aug 03 '22 17:08 jc-paris

Here is a video of what I do to test. After the AppStore app opens, I click "build & run" on Xcode:

jc-paris avatar Aug 03 '22 18:08 jc-paris

I appreciate that you shared a sample app, @jc-paris. I'm also trying the scenario shown on the video. Unfortunately, after testing multiple times, I'm still unable to reproduce it using the given MCVE (I just changed the bundle ID and GoogleService-Info.plist). I have a feeling that there's a misconfiguration in your FDL or maybe a project-specific issue. Is the result of your URL always nil every time you run the app?

In addition to that, note that disabling pasteboard access affects the app in the following ways as discussed here:

  • Deferred deep-linking will not work as reliably. At best, your app receives weak matches for deep-links
  • App install attribution stats will be less accurate (potentially undercounting app installs)

rizafran avatar Aug 04 '22 13:08 rizafran

Hello @rizafran,

What could be misconfigured in my link (the link is public, you can have a look at it to see what could be missing. I didn't see any param related to fingerprinting. Only efr to skip the preview page. Speaking of it, it is still required for fingerprinting or can we omit it as its purpose is to copy the link which will no longer be used ?).

The GoogleService-Info.plist file is also included in the MCVE (which I downloaded from Firebase console), is it missing anything ? What could be misconfigured in the project (to know where I could look) ? For the MCVE I created a project from scratch so I'm not sure to understand what could be missing..

Can it be anything device related ?

Also, what do you think of this ?

While browsing Firebase Dynamic Link code, I notice this comment in the code: https://github.com/firebase/firebase-ios-sdk/blob/97aff9edf50601bd9ab39ea29c8b1e6e020efe80/FirebaseDynamicLinks/Sources/FIRDLDefaultRetrievalProcessV2.m#L142 Which would suggest that another request should be made using fingerprinting when there is no uniq match (which I believe is the case here). But I never see a second request, nor found the code of that request..

jc-paris avatar Aug 04 '22 13:08 jc-paris

@jc-paris, I forgot to mention that I'm unable to test the MCVE using your GoogleService-Info.plist and bundle ID because I need to run the app in my device (in which I'm getting a provisioning profile issue) as there's an error when opening the link through simulator. Regarding your question on fingerprinting, I'll ask the team first about this.

rizafran avatar Aug 04 '22 19:08 rizafran

Hi @jc-paris, you can omit the fingerprinting, but you still need to disable the preview page in the Firebase console or by adding efr=1 in the FDL link.

rizafran avatar Aug 05 '22 17:08 rizafran

Why do you mean by "I can omit the fingerprinting" ?

jc-paris avatar Aug 05 '22 17:08 jc-paris

@jc-paris oops sorry for the misunderstanding. Please ignore my answer above. I'll check again with the team.

rizafran avatar Aug 05 '22 18:08 rizafran

@jc-paris, I'm still confirming with the team regarding your question. In the meantime, we'd like to confirm if you enabled the "allow tracking" on your device? We suspect that disabling that will cause the SDK to not collect the device heuristics therefore we can't provide a weak match.

rizafran avatar Aug 08 '22 19:08 rizafran

Hello,

Are you referring to anything else than Privacy > Tracking > Allow Apps to request to track ? On both device where I do the test, it activated.

Because neither in the sample, or my app, I'm asking for such consent (using App Tracking Transparency) upon launch. So when Firebase make the first install match, it won't have any consent. And as far as I know, such consent only prevent access to IDFA, there is no other system stuff that can't be accessed because it could be denied 🤔

jc-paris avatar Aug 08 '22 19:08 jc-paris

@jc-paris yep, thanks for the update. The team is also unable to reproduce the issue using the quickstart app. To isolate, could you try reproducing it using another FDL domain or Firebase project?

rizafran avatar Aug 09 '22 17:08 rizafran

I reproduce the issue with my production app and the project I created specifically for the QuickStart (on which I can invite you if you'd like).

On my end it's the same behavior.

It might be something I'm doing wrong but I don't see what.. 😕

jc-paris avatar Aug 09 '22 17:08 jc-paris

Just want to add if you have tried testing it using different networks?

rizafran avatar Aug 10 '22 10:08 rizafran

I've tried at the office, at home (Wi-Fi for both) and in 4G. Issue remain the same...

jc-paris avatar Aug 10 '22 10:08 jc-paris

@jc-paris I'm a Firebaser (but not an FDL expert) working on a SwiftUI version of the quickstart. I found Apple's diagnostic tool to be helpful for debugging. Sorry if I missed it in the thread but have you tried putting your URL into Settings --> Developer --> (Universal Links) Diagnostics on your iPhone?

Note: You shouldn't need to enable the Associated Domains Development toggle beside it unless you're using ?mode=developer on your Associated Domains entitlement and you can still use the Diagnostics tool regardless.

andrewheard avatar Aug 10 '22 21:08 andrewheard

@andrewheard I'm not sure to understand how this relates to my issue.

The dynamic link works well when the app is installed, and also works when app not installed and pasteboard is enabled. But it doesn't work anymore if I disable the pasteboard and try to open the dynamic link (the app doesn't retrieve the link upon launch). Fingerprinting should take over and get me a weak match of the dynamic link. Instead I get no match.

The Universal Links Diagnostic just tell me that the URL is not a universal link for any installed app (which is true before I install the app). As we don't use the "universal link" mechanism to open the app when not installed I don't see how this is helpful.

jc-paris avatar Aug 11 '22 05:08 jc-paris

Ah, sorry @jc-paris , I misunderstood. The Universal Links Diagnostic tool helped me diagnose an issue with the app not opening after it was installed but I now see the exact flow you followed in your screenshot. Thanks for posting that, I'll see if I run into the same issue.

andrewheard avatar Aug 11 '22 14:08 andrewheard

We have also come across this issue. We tested two devices side by side with the same privacy settings, works on one all the time while the match fails all the time on the other.

Then we realised that the device that was failing had the iCloud Private Relay activated. After turning it off and opening the dynamic link again, the match worked on a fresh install.

baldursson avatar Oct 14 '22 07:10 baldursson

@baldursson Thanks for that one, that did the trick for me. Very peculiar. 😅

rizkicalame avatar Jan 27 '23 20:01 rizkicalame

Should it be set to boolean FALSE, or, as official documentation mentions, to string "NO"? https://firebase.google.com/docs/dynamic-links/flutter/receive

FuadEfendi avatar Feb 19 '23 16:02 FuadEfendi