Hello you. I’m sure you’ve already used an app that can process URLs as it if was a web page. I’m sure you’ve come across a link that links to a page or a resource in an app, and when that app isn’t installed on your device, the link takes you to Playstore or AppStore and once you install the app, it leads you to the appropriate resource. This magic can be done with Firebase Dynamic Links. This article is about implementing these functionalities with Firebase Dynamic Links with Xamarin Forms and we will also cover how to create dynamic links from your C# back-end.
Setting Up Firebase Dynamic Links
Firebase dynamic links is not difficult to set up. First, you need to create a firebase project, obviously. Then enable dynamic links. The easiest way to get started is to use the default domain provided by firebase which is “.page.link”. The process of setting this up is well documented, and I won’t go through it here. Here is a link to a video that will you through setting this up on Android and iOS.
Creating Firebase Dynamic LInks from a Back-end in C#
In case you need to share firebase dynamic links from your server to point to resources in your app, you can use simple HTTP calls to the Firebase rest API. Here is a link to the documentation of this API. What we will do next is create a short dynamic link in C#.
First, you need to get the API key of your firebase project. You can do so by following the steps here in this page.
Note: Data passed to a firebase dynamic link is always in the form of a URL, so that if the final dynamic link is clicked on a desktop environment, the link is opened on the browser.
By the way, check my previous post about firebase push notifications for .NET. In case you want to implement firebase push notifications in your ASPnet core back-end and Xamarin Forms app, or you find it difficult to implement certain scenarios like receiving notifications in the background etc… This post will guide you.
Taking the above point into consideration, we will have to pass our data as get parameters in a URL that will point to our website. In my case, I’ll like to send a “ProductId, OwnerId, and ProductName” so I’ll add this info as get parameters to my URL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | string doumerBaseUrl = $"https://doumer.me"; var qs = new Dictionary<string, string> { { "product_id", authToken }, { "owner_id", isNewAccount.ToString() }, { "product_name", isSubscriber.ToString() } }; // Build the result url var finalCustomUrl = doumerBaseUrl + "?" + string.Join( "&", qs.Where(kvp => !string.IsNullOrEmpty(kvp.Value) && kvp.Value != "-1") .Select(kvp => WebUtility.UrlEncode(kvp.Key) + "=" + WebUtility.UrlEncode(kvp.Value))); |
Next, construct the URL leading to the firebase API, by adding our API Key at the end. as follows:
1 | https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key={_settings.FirebaseAPIKey} |
To configure your dynamic link, you’ll need to create a Dynamic Link info json object and pass it as the request body. This object contains the appropriate parameters to configure the behavior of your dynamic link. Like:
- Telling if the link should open the play store or app store if the app is not installed
- The link to open when the app isn’t installed.
- The package name of the Android or iOS app to use to open the link
- Your app’s App Store ID, used to send users to the App Store when the app isn’t installed
All of the detail needed to construct this object, with the description of each of its properties can be found here.
NOTE: To prevent your Dynamic Link from being crawled, in case you use it for sensitive information, set the suffix to “UNGUESSABLE” As I’ll do in the example below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | var stringbody = JsonConvert.SerializeObject(new { DynamicLinkInfo = new { DomainUriPrefix = _settings.doumerDomainUriPrefix, Link = finalCustomUrl, AndroidInfo = new { _settings.AndroidPackageName }, IosInfo = new { IosBundleId = _settings.IOSBundleId, IosAppStoreId = _settings.IOSAppstoreId } }, Suffix = new { Option = "UNGUESSABLE" } }, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); var result = await httpclient.PostAsync(url, new StringContent(stringbody, Encoding.UTF8, "application/json")); var stringContent = await result.Content.ReadAsStringAsync(); if (!result.IsSuccessStatusCode) { var reason = result.ReasonPhrase; throw new Exception($"{stringContent}\n\r {reason}"); } var dynamicLink = JsonConvert.DeserializeObject<FirebaseDynamicLink>(stringContent); |
The request sends you the short dynamic link as a response. In case there is an error, you’ll receive the appropriate error message. The error messages returned are descriptive.
Note: You should add the signature of your android package to the firebase project that you create dynamic links for. Else you’ll have an error when creating your dynamic link.
Note: In case your dynamic link doesn’t behave as you wish, there is a way to debug it. Just follow the steps in this guide.
Consuming Firebase Dynamic Links in your Xamarin Forms Project
Xamarin Android Project
First, you’ll need to install this package(Xamarin.Firebase.Dynamic.Links) in your android project, to manipulate dynamic links.
In the initial activity (in my case, the startup activity) we add an intent filter to listen to dynamic link intents for my host.
Then, inside the OnCreate method we check each intent and if it is a dynamic link, we handle it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault }, DataScheme = "https", DataHost = "doumer.me")] public class SplashActivity : Activity { protected override async void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); StartActivity(new Intent(Application.Context, typeof(MainActivity))); await HandleDynamicLink(Intent); } } |
To handle the dynamic link, it is easy, here is an example below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | async Task HandleDynamicLink(Intent intent) { var result = await FirebaseDynamicLinks.Instance.GetDynamicLink(intent); if (result != null) { var dynamicLink = (PendingDynamicLinkData) result; var deepLink = dynamicLink.Link; if (deepLink != null) { _logger.LogInformation($"We got a deeplink {deepLink}"); var productId = deepLink.GetQueryParameter("product_id"); var ownerId = deepLink.GetQueryParameter("owner_id"); var prodName = deepLink.GetQueryParameter("product_name"); //TODO: do what ever you wish with the data gotten from your dynamic link } } } |
Xamarin iOS
Things are a little bit more complicated on iOS. You’ll need to configure your provisioning profiles, entitlements etc… for this to work properly. In this video, you’ll see how to configure profiles and capabilities for your project to have firebase dynamic links on appstore connect.
Once you are done with the above configuration, install the package (Xamarin.Firebase.iOS.DynamicLinks). In your iOS project.
You will then need to override override OpenUrl (UIApplication, NSUrl, string, NSObject)
method to support iOS 8 or older and OpenUrl (UIApplication, NSUrl, NSDictionary) for iOS 9 and above. method to support iOS 9 or newer. This is to handle links received through your a custom URL scheme. In the example below (Gotten from github) you can see how it is done.
1 2 3 4 5 6 7 8 9 10 11 | public override bool OpenUrl (UIApplication application, NSUrl url, string sourceApplication, NSObject annotation) { var dynamicLink = DynamicLinks.SharedInstance?.FromCustomSchemeUrl (url); if (dynamicLink == null) return false; // Handle the deep link. For example, show the deep-linked content or // apply a promotional offer to the user's account. return true; } |
To handle links received through universal links, override the method
1 | ContinueUserActivity (UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler) |
Then, get your link and extract the parameters from it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler) { return DynamicLinks.SharedInstance.HandleUniversalLink(userActivity.WebPageUrl, (dynamicLink, error) => { try { if (error != null) { _logger.ReportError(new Exception(error.LocalizedDescription), "Error while getting dynamic link."); return; } DynamicLink = dynamicLink.Url.ToString(); //TODO: get the parameters from your dynamic link here } catch (Exception e) { _logger.ReportError(e, "Error while handeling URL callback in appdelegate."); } }); } |
Conclusion
Now you can open links that lead to your app and point to specific resources. We only covered the essential part for Xamarin and C# most of the firebase configuration stuff is well documented already, so I left several links. You might also be interested in this advanced guide to how to implement firebase push notifications in your aspnet core back-end and Xamarin Forms apps.
Follow me on social media and stay updated