Firebase dynamic link not opening correct app when multiple flavors are installed on iOS - ios

We developed a flutter app for Android and iOS, with different flavors: dev, test and prod, so we have 6 apps in total. To on-board the user, we send a firebase dynamic link via Email (with a deep link inside it) to navigate the user to a specific screen when it is tapped.
The expected behavior is that when the user taps on a dynamic link of - say - the dev app, it opens a screen in the dev app. Similar for the other flavors.
Now this works just fine on Android.
On iOS it works fine if only one app is installed, but if for example the dev and the test apps are installed, then tapping on the dynamic links always opens the test app. This is also true when dev, test and prod are installed: test is opened.
This is a development issue and not relevant for production as the user will never have the test or dev app installed, but it is annoying us as we have to uninstall and reinstall flavors all the time.
Our dynamic links have the following format (values in '<>' are placeholders):
Dev: https://<app_id>.page.link/?link=http://dev.<mydomain>.com/reset?token=token1&apn=<mypackage>.dev&isi=<isiNumber1>&ibi=<mypackage>.dev
Test: https://<app_id>.page.link/?link=http://test.<mydomain>.com/reset?token=token2&apn=<mypackage>.test&isi=<isiNumber2>&ibi=<mypackage>.test
Prod: https://<app_id>.page.link/?link=http://<mydomain>.com/reset?token=token3&apn=<mypackage>&isi=<isiNumber3>&ibi=<mypackage>
The behavior is the same for all iOS versions I could get my hands on on real devices, i.e. iOS 11, 12 and 13.
We're using Flutter 1.9.1-hotfix6 and firebase_dynamic_links 0.5.0+1
Any ideas what this might be caused by?

Firebase Dynamic Links do not support using the same URL prefix for multiple iOS apps/targets contained in the same Firebase project.
You can workaround this in multiple ways though:
Using multiple (sub)domains (as already suggested by Janmenjaya)
Use a custom domain
Using multiple Firebase projects (as already suggested by Aleksandr)
On Android it works out of the box, because you are in charge of matching paths with particular apps within the Manifest file. On iOS it doesn't work, because Firebase is in charge of such matches within the hosted apple-app-site-association file.
For further information, I've written an extensive answer here.

Do not use one project in the firebase console, it is better to split and use different url in <key>com.apple.developer.associated-domains</key>

In Firebase under dynamic link, we can create multiple url domain. And these url domain we need to add in the associated domain of different target.
Steps
Let’s assume I have two target test and production.
I created two domain link like “test.page.link” and production.page.link
In test target in Xcode under Signing & Capabilities -> Associated Domain, use the “test.page.link”
And for production target set the production.page.link

Related

Firebase dynamic link always goes to ios app store even if app installed

I have a dynamic link that is working fine on Android however I can't get the App Store redirect behaviour working correctly on iOS.
If I set up the dynamic link to go to a url (not the app store) if the app is not installed it works as expected and opens the app. This is the dynamic link:
https://go.xxxxx.app/?link=https://member.xxxxx.app&apn=app.xxxxx.xxxxx&isi=1573527302&ibi=app.xxxxx.xxxxx&ifl=https://member.xxxxx.app&efr=1
However if I set it to go to the app store if the app is not installed it ALWAYS goes to the app store, even if the app is installed.
https://go.xxxxx.app/?link=https://member.xxxxx.app&apn=app.xxxxx.xxxxx&isi=1573527302&ibi=app.xxxxx.xxxxx&efr=1
I am obviously doing something wrong or misunderstand the relationship between deep links and dynamic links. "go" is my dynamic link subdomain and "member" is my deep link subdomain.
I realise there are several other questions on this but none of the answers helped me.
Other info
I am using a physical iPhone 8 with iOS 15.4.1
This is my deeplink which works fine if I click the url on my device:
https://member.xxxxx.app
I have an app association file set up here:
https://member.xxxxx.app/.well-known/apple-app-site-association
I also set it here as I wasn't sure whether to set it up for the dynamic link as well:
https://go.xxxxx.app/.well-known/apple-app-site-association
I have the following Associated Domain set up in Xcode:
applinks:member.xxxxx.app
Note that I have not added the associated domain applinks:go.xxxxx.app as this just seemed to make the dynamic link be treated like a deeplink.
I have the capability associated domains turned on in my Apple Developer identifier.
My app is published to the app store but not the latest version of the app with the associated domain member.xxxxx.app.
I have added my app and team id to Firebase on the ios app.
I have "Associated Domains Development" turned on in the developer settings of my iPhone.
I added FirebaseDynamicLinksCustomDomains in my info.plist as mentioned here:
https://firebase.google.com/docs/dynamic-links/custom-domains#set_up_a_custom_domain_in_the
It appears I needed to add applinks:go.xxxxx.app to the Associated domains as well. I can't test from the App Store if the link parameter works I guess I will have to wait until I release to the store.
So the dynamic link is also a deep link that contains another deep link.
Kind of confusing. If anyone can add some more info or explanation that would be great.
I will leave the question here for now as it may help people.
I have the following Associated Domain set up in Xcode: applinks:member.xxxxx.app Note that I have not added the associated domain applinks:go.xxxxx.app as this just seemed to make the dynamic link be treated like a deeplink.
Edit:
To get the dynamic link working in iOS see my answer here:
Firebase short dynamic link not working in iOS (being treated as a deeplink)

Firebase Analytics events on iOS - test and production

The iOS app I am working on uses Firebase Analytics to report events. It works as expected, but the app is not in production yet. Once it is it would be preferable to have the events logged by real users separate from these logged when debugging.
What is the best way to have Firebase Analytics events logged separately for test and production?
First you will probably want to create a separate Firebase project for staging/debug.
Then you will have to configure your app to be able to use different resources based on build type. For Android we solved this using build flavors, not sure what the iOS equivalent is.
From docs (https://firebase.google.com/docs/projects/multiprojects):
By default, FirebaseApp.configure() will load the GoogleService-Info.plist file bundled with the application. If your development and production environments are configured as separate targets in XCode, you can:
Download both GoogleService-Info.plist files
Store the two files in different directories
Add both to your XCode project
Associate the
different files with the different targets using the Target
Membership panel.
If the builds are part of a single target, the best option is to give both configuration files unique names (e.g. GoogleService-Info-Free.plist and GoogleService-Info-Paid.plist). Then choose at runtime which plist to load.

Universal links for iOS apps - how it works?

I am new to adding universal links to iOS applications. I have read some materials but still have a few questions below. Any pointer will be greatly appreciated!
When exactly Apple will crawl my domain and inspect the [domain]/apple-app-site-association content? I have a new domain, and I'm wondering how Apple's crawler can discover it?
What's the recommended way to test universal links locally before publishing the first version of my app?
Is version control for universal links not possible? For example, the app 1.0 version only supports \item universal link, but app 2.0 version supports one more schema \details . If I specify both paths in apple-app-site-association, then the 1.0 app will break when user navigate to \details. (Edit: I noticed that if the app appropriately set it to be unhandled, then we can still fall back to browser.)
Thanks!
When a device downloads an app, it looks for an entitlements file to list out your associated domains. When it finds that your app has associated domains, it will check those domains for the aasa and download it onto the device. The aasa for that app will only be downloaded on install and update so changes you make will not effect all of your apps.
For testing you can host your AASA on a testing domain or on your production domain. It's up to you but you have to remember to update your entitlements file when you push it to production to ensure that you have the right domain configured. Every time you rebuild the app, it should re-download the aasa so testing shouldn't be too difficult. Always remember to paste the link in notes and not type it into Safari. Universal links only work when they are tapped, not typed in.
For your example you should make sure your new AASA is published at the exact time you publish your app. You should probably use a separate testing domain to host your AASA. You can just include both domains in your entitlements.
Branch actually has testing environment and AASA hosting built in if you'd prefer not to handle all of that on your own. They also leverage URI schemes in cases where Universal Links don't work.

Firebase dynamic links for multiple iOS apps in project

I have a firebase project with two iOS apps and two Android apps.
These apps needs to share databases and users so this design seems natural.
Regarding dynamic links, Android works like a breeze but I’m struggling with the iOS part.
Basic dynamic links setup is easy, the difficult (impossible?) part is to make dynamic link that routes toward the proper app, based on bundleID.
Firebase auto-generates the apple-app-site-association files but the paths components for all apps is always the same : ["/*"]
{"applinks":
{"apps":[],
"details":[
{"appID":"XXXXX.com.test.app1","paths":["/*"]},
{"appID":"XXXXX.com.test.app2","paths":["/*"]}]
}
}
As a consequence, the first app app1 always match and all deep links are directed towards this app.
At this point, i'm unable to open a dynamic link to app2.
The documentation is inexistant for this configuration, even if this fully functional on Android apps.
Am i missing something here ?
Firebase Dynamic Links has limited support for multiple iOS Apps in the same project. We are planning to improve this support, but no ETA on the dates, likely Q1 2018.
Here is one of the most typical example of Firebase Dynamic Links setup for several iOS App in one project: https://photos.app.goo.gl/apple-app-site-association
You still should be able to open app2, if app1 is not installed on iOS device.
I believe you can change order of the Apps in apple-app-site-association by deleting app1 and re-adding app1 to the project.
We do receive more requests on allowing to re-order priority of the App in apple-app-site-association file. For example, developers have free and paid App, so they actually want for dynamic link to work in both Apps.
As a workaround, you may be able to use customURL scheme to re-open correct app2, if app1 was opened when this was not desired. This would be not the best user experience.
Let me know if you have more questions, feel free to open Firebase support ticket to share private information.
As Oleksiy Ivanov has already pointed out, this boils down to the problem, that Firebase Dynamic Links doesn't support using the same URL prefix for multiple iOS apps/targets contained in the same Firebase project.
There are multiple workarounds though:
Using multiple (sub)domains
Use a custom domain
Using multiple Firebase projects
On Android it works out of the box, because you are in charge of matching paths with particular apps within the Manifest file. On iOS it doesn't work, because Firebase is in charge of such matches within the hosted apple-app-site-association file (as you've already pointed out in your question).
For further information, I've written an extensive answer here.

Long list of domains in iOS Entitlement file in iOS 9.0-9.2

We have a need to support 100+ domains in our entitlements file for Universal Links.
Example:
applinks:test.myapp.com
applinks:blah.myapp.com
applinks:foo.bar.com
etc...
I know that *.myapp.com will be supported in iOS 9.3, but is there a way to do this elegantly for customers using iOS 9.0 to 9.2 without having to manually add 100+ entries to the entitlements file? Is there a way to do this without having to rebuild and re-release our app every time we need to add a domain to the list?
Thanks!
The new wildcard support in iOS 9.3 is designed for exactly the situation you're describing, so there isn't really a solid alternative in earlier OS versions.
If you don't want to worry about continually updating the list of subdomain applinks entries (or even if you do, but need to wait for App Store review), the best workaround is probably hosting fallback pages on each subdomain with a call-to-action the user can use to continue into the app. That would work as follows:
Assume that you have applinks:mydomain.com configured.
User opens a link to new.mydomain.com/exciting-page (which is NOT covered by the entitlement above).
User sees a custom interstitial, functionally similar to something like this. On this interstitial is a link pointing to mydomain.com/new/exciting-page
User opens the link and the app launches.
The only thing I am not sure about is whether mydomain.com and new.mydomain.com count as 'different domains' for the purpose of Universal Links, since Universal Linking functionality is disabled in Safari for links within the same domain (source). If this turns out not to work, you could easily use something like applinks:mydomain.io and a link to mydomain.io/new/exciting-page in step 3 instead.

Resources