Flutter - Firebase Dynamic Link is not caught by onLink but open the app on iOS

Viewed 4118

Everything works fine on android but on ios when the app is already opened clicking the link takes the app in the foreground but the onLink method is not call.

Link:

https://<url>/?link=<link>&apn=<apn>&ibi=<bundle>&isi=<isi>

Package:

  • firebase_dynamic_links: ^0.6.3

Code

import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:flutter/material.dart';

class DynamicLinksService {

  Future handleDynamicLinks(BuildContext context) async {
    final PendingDynamicLinkData data =
        await FirebaseDynamicLinks.instance.getInitialLink();

    await _handleDynamicLink(context, data);

    FirebaseDynamicLinks.instance.onLink(
        onSuccess: (PendingDynamicLinkData dynamicLinkData) async {
      await _handleDynamicLink(context, dynamicLinkData);
    }, onError: (OnLinkErrorException e) async {
      print('Dynamic link failed: ${e.message}');
    });
  }

  Future _handleDynamicLink(
      BuildContext context, PendingDynamicLinkData data) async {
    final Uri deepLink = data?.link;
    if (deepLink != null) {
      print('_handleDeepLink | deepLink $deepLink');

      await _doSomething(context, deepLink.toString());
    } else {
      print('no deepLink');
    }
  }
}

2 Answers

From my experimentation, onLink is not called on iOS however you can call getInitialLink() and it will contain the link. I'm uncertain if this is by design or a bug, but it seems to be across a few versions.

Example service code:

  Future<Uri> retrieveDynamicLink(BuildContext context) async {
    try {
      final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.getInitialLink();
      final Uri deepLink = data?.link;
      return deepLink;
    } catch (e) {
      print(e.toString());
    }

    return null;
  }

Widget snippet

  @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){
        final _timerLink = Timer(
          const Duration(milliseconds: 1000),
              () async {
            final auth = Provider.of<FirebaseAuthService>(context, listen: false);
            final link = await auth.retrieveDynamicLink(context);
            _handleLink(link);
          },
        );
      }
  }

Make sure to add the WidgetsBindingObserver

class _SignInPageState extends State<SignInPage> with TickerProviderStateMixin, WidgetsBindingObserver{

I'm not sure why this works but you'd first have to call FirebaseMessaging.instance.getInitialMessage() at least once before your onLink callback is activated by Firebase.

Not sure if this is by design or a bug.

Let me know if this works.

Related