How to implement deep linking in flutter, with redirect to app store?

15,518

Solution 1

You can use Firebase dynamic links for this purpose:

https://firebase.google.com/docs/dynamic-links

There it says:

if a user opens a Dynamic Link on iOS or Android and doesn't have your app installed, the user can be prompted to install it; then, after installation, your app starts and can access the link.

You can find information on how to implement this with Flutter here:

https://pub.dev/packages/firebase_dynamic_links

I have tried it myself with Android and iOS and it worked fine. If the app is not installed, the Google Play store or Apple AppStore is opened. The user can tap "Install" and then "Open". Afterward your app is started and the dynamic link is sent to your app (on iOS via the clipboard) where you can access it as explained on the website above. I.e. right after the start of your app in the first initState method you can call

final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.retrieveDynamicLink();
final Uri deepLink = data?.link;

to get the deep link. However in my experience on iOS this is too early to retrieve the link. I got "null" when trying it. It seemed to take a moment. I then used a WidgetsBindingObserver and watched in the didChangeAppLifecycleState method for AppLifecycleState.resumed. There I called retrieveDynamicLink. Due to a permission request (if the user allows notifications) the method was called twice. The first time it returned null but when it was called the second time it returned the deep link. So my solution looks like this:

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _retrieveDynamicLink();
    }
  }

  /**
   * Laden des Deep Link nach der Installation.
   */
  Future<void> _retrieveDynamicLink() async {
    final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.retrieveDynamicLink();
    final Uri deepLink = data?.link;

    if (deepLink != null) {
        // Use the deepLink
        // ...
    }
}

Solution 2

As of iOS 12 there is no way to have a direct application deep link that redirects to the app store if your application is not installed.

You can have a deep link to the app store or a deep link within your app using the meta tag apple-itunes-app on a website. But this only shows a small banner at the top of the page, and is not a true deep link.

One system that I haven't used before but might be worth checking out as well is branch.io. You might be able to achieve something like that with their system, but I'm not exactly sure how it works. It for sure is not native as part of iOS 12.

Solution 3

I am answering late but it will might help to others.

We can use firebase dynamic links for deep linking in a flutter with firebase_dynamic_links plugin. Refer this link for full implementation steps and create and receive a link, https://medium.com/better-programming/deep-linking-in-flutter-with-firebase-dynamic-links-8a4b1981e1eb. Here is a sample code for receiving a link inside the app and open a specific screen.

class MainWidgetState extends State<MainWidget> {

  @override
  void initState() {
    super.initState();
    this.initDynamicLinks();
  }

  initDynamicLinks(BuildContext context) async {
    await Future.delayed(Duration(seconds: 3));
    var data = await FirebaseDynamicLinks.instance.getInitialLink();
    var deepLink = data?.link;
    final queryParams = deepLink.queryParameters;
    if (queryParams.length > 0) {
      var userName = queryParams['userId'];
      openSpecificScreen(userName);
    }
    FirebaseDynamicLinks.instance.onLink(onSuccess: (dynamicLink)
    async {
      var deepLink = dynamicLink?.link;
      final queryParams = deepLink.queryParameters;
      if (queryParams.length > 0) {
        var userName = queryParams['userId'];
        openSpecificScreen(userName);
      }
      debugPrint('DynamicLinks onLink $deepLink');
    }, onError: (e) async {
      debugPrint('DynamicLinks onError $e');
    });
  }

  openSpecificScreen(String userName){
    Navigator.of(context).pushNamed("routeFormScreen", arguments: {"name": userName});
  }
}
Share:
15,518
Ayush Shekhar
Author by

Ayush Shekhar

Ping me for anything flutter.

Updated on June 28, 2022

Comments

  • Ayush Shekhar
    Ayush Shekhar almost 2 years

    Is there a way to achieve deep linking in a flutter, so that if a user clicks on a link then they are redirected to a specific part of the app, given that the app is installed, but if it isn't, they are redirected to the respective app store, to install the application and then taken to that specific part?

    While searching for a solution I came across this package called uni_links but I am not sure if it can fulfill this requirement.