Firebase Dynami c Ссылка не перехватывается getInitialLink, если приложение закрывается и открывается по этой ссылке - PullRequest
3 голосов
/ 21 января 2020

Динамически сгенерированные динамические c ссылки неправильно отлавливаются

FirebaseDynamicLinks.instance.getInitialLink().

, если приложение закрыто. Однако, если приложение открыто, слушатель правильно обнаруживает новые входящие динамические ссылки c. Мне не ясно, если это проблема установки, как я генерирую ссылку Dynami c.

Для воспроизведения

Сначала настройте Firebase для проекта Flutter, как описано в документации. Затем для установки динамической c ссылки:

/// See also
/// https://firebase.google.com/docs/dynamic-links/use-cases/rewarded-referral
/// how to implement referral schemes using Firebase.
Future<ShortDynamicLink> buildDynamicLink(String userId) async {
  final PackageInfo packageInfo = await PackageInfo.fromPlatform();
  final String packageName = packageInfo.packageName;

  var androidParams = AndroidParameters(
    packageName: packageInfo.packageName,
    minimumVersion: Constants.androidVersion, // app version and not the Android OS version
  );

  var iosParams = IosParameters(
    bundleId: packageInfo.packageName,
    minimumVersion: Constants.iosVersion, // app version and not the iOS version
    appStoreId: Constants.iosAppStoreId,
  );

  var socialMetaTagParams = SocialMetaTagParameters(
    title: 'Referral Link',
    description: 'Referred app signup',
  );

  var dynamicLinkParams = DynamicLinkParameters(
    uriPrefix: 'https://xxxxxx.page.link',
    link: Uri.parse('https://www.xxxxxxxxx${Constants.referralLinkPath}?${Constants.referralLinkParam}=$userId'),
    androidParameters: androidParams,
    iosParameters: iosParams,
    socialMetaTagParameters: socialMetaTagParams,
  );

  return dynamicLinkParams.buildShortLink();
}

Эта динамическая c ссылка затем может быть передана другим новым пользователям.

Я слушаю начальные ссылки при запуске приложения и затем для новых входящих ссылок.

1) Ссылка правильно открывает приложение, если приложение не запущено, но getInitialLink не получает его.

2) Если приложение открыто, ссылка является правильно перехвачен слушателем и все работает.

Вот очень простой файл main.dart, который я использовал для проверки 1), что исходная ссылка не найдена с FirebaseDynamicLinks.instance.getInitialLink ().

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  PendingDynamicLinkData linkData = await FirebaseDynamicLinks.instance.getInitialLink();
  String link = linkData?.link.toString();
  runApp(MyTestApp(link: link));
}

class MyTestApp extends StatelessWidget {
  final String link;

  MyTestApp({this.link});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        builder: (BuildContext context, Widget child) {
          return Scaffold(
            body: Container(
              child: Center(
                  child: Text('Initial dynamic Firebase link: $link')
              ),
            ),
          );
        }
    );
  }
}

Ожидаемое поведение

Ссылка должна открывать приложение и запускать FirebaseDynamicLinks.instance.getInitialLink()..

Дополнительный контекст

Надеюсь, правильно настроенный проект Firebase с консолью Firebase. Чтобы убедиться в этом, я создал динамическую c ссылку для использования с Firebase Auth 'регистрация по электронной почте', и эти динамические c ссылки работают должным образом, даже если приложение не открыто.

Дело в том, что реферальная динамическая ссылка c, которую я генерирую программным способом, открывает приложение, когда оно закрывается, но затем не обрабатывается FirebaseDynamicLinks.instance.getInitialLink(), и, что еще более запутанно, работает, как и ожидалось, если приложение открыто. В этом случае он перехватывается слушателем FirebaseDynamicLinks.instance.onLink.

Я также настроил WidgetsBindingObserver во Flutter для обработки этого обратного вызова по мере необходимости, когда приложение вернуло фокус.

Любая помощь очень ценится. Отладка очень сложна, так как вам нужно делать это на реальном устройстве, а не в симуляторе. Что еще хуже, я не понял, как подключить отладчик, в то время как ссылка Dynami c открывает приложение. Это означает, что я также застрял в дальнейшем изучении этого вопроса.

Ответы [ 2 ]

0 голосов
/ 03 апреля 2020

Я попытался ответить на вопрос Рохита, и поскольку несколько человек сталкиваются с одной и той же проблемой, я добавляю сюда еще несколько деталей. Я создал виджет с сохранением состояния, который я помещаю в верхней части дерева виджетов прямо под приложением материала:

class DynamicLinkWidget extends StatefulWidget {
  final Widget child;

  DynamicLinkWidget({this.child});

  @override
  State<StatefulWidget> createState() => DynamicLinkWidgetState();
}

class DynamicLinkWidgetState extends State<DynamicLinkWidget> with WidgetsBindingObserver {

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    locator.get<DynamicLinkService>().initDynamicLinks();
  }

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

  @override
  Widget build(BuildContext context) {
    return Container(child: widget.child);
  }
}

Я использую пакет getit для внедрения сервисов. Служба ссылки Dynami c выглядит примерно так:

class DynamicLinkService {
  final UserDataService userDataService;

  final ValueNotifier<bool> isLoading = ValueNotifier<bool>(false);

  final BehaviorSubject<DynamicLinkError> _errorController = BehaviorSubject<DynamicLinkError>();

  Stream<DynamicLinkError> get errorStream => _errorController.stream;

  DynamicLinkService({@required this.userDataService});

  void initDynamicLinks() async {
    final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.getInitialLink();
    final Uri deepLink = data?.link;

    if (deepLink != null) {
      processDynamicLink(deepLink);
    }

    FirebaseDynamicLinks.instance.onLink(
        onSuccess: (PendingDynamicLinkData dynamicLink) async {
          final Uri deepLink = dynamicLink?.link;
          if (deepLink != null) {
            print('=====> incoming deep link: <${deepLink.toString()}>');
            processDynamicLink(deepLink);
          }
        },
        onError: (OnLinkErrorException error) async {
          throw PlatformException(
            code: error.code,
            message: error.message,
            details: error.details,
          );
        }
    );
  }

  Future<void> processDynamicLink(Uri deepLink) async {
    if (deepLink.path == Constants.referralLinkPath && deepLink.queryParameters.containsKey(Constants.referrerLinkParam)) {
      var referrer = referrerFromDynamicLink(deepLink);
      userDataService.processReferrer(referrer);
    } else {
      await FirebaseEmailSignIn.processDynamicLink(
          deepLink: deepLink,
          isLoading: isLoading,
          onError: this.onError
      );
    }
  }

  void onError(DynamicLinkError error) {
    _errorController.add(error);
  }
}

Вы видите, что мое приложение должно обрабатывать два типа ссылки Dynami c, одна для регистрации по электронной почте, другая наша реферальная ссылка, которая используется для объединения пользователей и позволяет нам понять, кто представил нам нового пользователя. Эта настройка работает сейчас для нас. Надеюсь, это поможет и другим.

0 голосов
/ 21 января 2020
  • В DynambaseDynamicLinks Два метода 1) getInitialLink () 2) onLink () .

  • Если, когда ваше приложение открыто и вы нажимаете на ссылку Dynami c, тогда будет вызываться FirebaseDynamicLinks.instance.onLink (), если ваше приложение убито или открыто из PlayStore, то вы получите из FirebaseDynamicLinks. instance.getInitialLink (); .

  • Сначала вам нужно инициализировать экземпляр FirebaseDynamicLinks.instance .

      static void initDynamicLinks() async {
        final PendingDynamicLinkData data =
            await FirebaseDynamicLinks.instance.getInitialLink();
        final Uri deepLink = data?.link;
    
        if (deepLink != null && deepLink.queryParameters != null) {
          SharedPrefs.setValue("param", deepLink.queryParameters["param"]);
        }
    
        FirebaseDynamicLinks.instance.onLink(
            onSuccess: (PendingDynamicLinkData dynamicLink) async {
          final Uri deepLink = dynamicLink?.link;
    
          if (deepLink != null && deepLink.queryParameters != null) {
            SharedPrefs.setValue("param", deepLink.queryParameters["param]);
          }
        }, onError: (OnLinkErrorException e) async {
          print(e.message);
        });
      }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...