Created
July 29, 2021 07:51
-
-
Save Meghatronics/9d672524f14c3964260bc972e22df1cd to your computer and use it in GitHub Desktop.
A dart service to handle dynamic (deep) linking for flutter apps using firebase.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; | |
| import 'package:flutter/widgets.dart'; | |
| import '../base/data_base_classes/data_base_classes.dart'; | |
| import '../base/view_base_classes/app_toast.dart'; | |
| import '../utilities/constants/constants.dart'; | |
| /// Original written by MajorE | |
| /// Github: Meghatronics | |
| /// Twitter: @MajorE_1 | |
| class DynamicLinkService { | |
| DynamicLinkService._(); | |
| static final instance = DynamicLinkService._(); | |
| DynamicLinkServiceConfig _config; | |
| void configure(DynamicLinkServiceConfig config) { | |
| _config = config; | |
| _registerService(); | |
| } | |
| Future _registerService() async { | |
| final data = await FirebaseDynamicLinks.instance.getInitialLink(); | |
| _handleDeepLink(data); | |
| FirebaseDynamicLinks.instance.onLink( | |
| onSuccess: (PendingDynamicLinkData dynamicLink) async => | |
| _handleDeepLink(dynamicLink), | |
| onError: (OnLinkErrorException e) async => | |
| _config.onError ?? | |
| AppToast.instance.error(null, e.message ?? 'Could not open link'), | |
| ); | |
| } | |
| Future<ApiResponse<String>> createDynamicLink( | |
| Map<String, String> data, { | |
| String metadataTitle, | |
| String metadataDescription, | |
| String metadataImageUrl, | |
| }) async { | |
| String param; | |
| param = ''; | |
| data.forEach((key, value) { | |
| param = '$param&$key=$value'; | |
| }); | |
| param = param.substring(1); | |
| final parameters = DynamicLinkParameters( | |
| uriPrefix: _config.uriPrefixFromFirebase, | |
| link: Uri.parse( | |
| '${_config.linkDataUrl ?? _config.uriPrefixFromFirebase}?$param'), | |
| androidParameters: AndroidParameters( | |
| packageName: '${_config.packageName}', | |
| fallbackUrl: _config.fallbackUrl, | |
| ), | |
| iosParameters: IosParameters( | |
| bundleId: '${_config.packageName}', | |
| appStoreId: '${_config.appStoreID}', | |
| fallbackUrl: _config.fallbackUrl, | |
| ), | |
| /* googleAnalyticsParameters: GoogleAnalyticsParameters( | |
| campaign: | |
| 'Share ${post.mediaType == MediaType.video ? 'video' : 'image'}', | |
| medium: 'social', | |
| source: 'fyiid', | |
| ), */ | |
| socialMetaTagParameters: SocialMetaTagParameters( | |
| title: metadataTitle ?? _config.metadataDefaultTitle, | |
| description: metadataDescription ?? _config.metadataDefaultDescription, | |
| imageUrl: | |
| Uri.tryParse(metadataImageUrl ?? _config.metadataDefaultImageUrl), | |
| ), | |
| ); | |
| try { | |
| final shortLink = await parameters | |
| .buildShortLink() | |
| .catchError((_) => throw NetworkException()); | |
| final shareLink = shortLink.shortUrl.toString(); | |
| return ApiResponse(data: shareLink); | |
| } catch (e) { | |
| return ApiResponse( | |
| error: InputFailure(errorMessage: 'Could not generate link'), | |
| ); | |
| } | |
| } | |
| void _handleDeepLink(PendingDynamicLinkData data) { | |
| final deepLink = data?.link; | |
| if (deepLink != null) { | |
| final linkData = deepLink.queryParameters; | |
| debugPrint(linkData.toString()); | |
| _config.onData(linkData); | |
| } | |
| } | |
| } | |
| class DynamicLinkServiceConfig { | |
| /// Set a uri prefix you've created on the Firebase console of this project | |
| final String uriPrefixFromFirebase; | |
| final String linkDataUrl; | |
| /// Link to open instead of opening PlayStore or AppStore to download | |
| /// this app. | |
| /// | |
| /// If ```==null``` dynamic link will launch store if app is not installed. | |
| /// | |
| /// Else dynamic link will launch app page on the device store. | |
| final Uri fallbackUrl; | |
| /// Package name of this project. | |
| final String packageName; | |
| final String appStoreID; | |
| final String metadataDefaultTitle; | |
| final String metadataDefaultDescription; | |
| final String metadataDefaultImageUrl; | |
| /// Callback to run when handling dynamic link. | |
| /// | |
| /// When data is received, this function is run with the data | |
| final void Function(Map<String, String> data) onData; | |
| /// Callback to run when handling dynamic link. | |
| /// | |
| /// When error is generated this function runs with an [errorDescription] | |
| /// String | |
| final void Function(String errorMessage) onError; | |
| const DynamicLinkServiceConfig({ | |
| @required this.uriPrefixFromFirebase, | |
| @required this.packageName, | |
| @required this.appStoreID, | |
| @required this.onData, | |
| this.linkDataUrl, | |
| this.fallbackUrl, | |
| this.metadataDefaultTitle = appName, | |
| this.metadataDefaultDescription = '', | |
| this.metadataDefaultImageUrl, | |
| this.onError, | |
| }); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment